dolibarr 21.0.0-alpha
connector.lib.php
1<?php
2/*
3 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
4 * Copyright (C) 2003-2010 Frederico Caldeira Knabben
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * == BEGIN LICENSE ==
9 *
10 * Licensed under the terms of any of the following licenses at your
11 * choice:
12 *
13 * - GNU General Public License Version 2 or later (the "GPL")
14 * https://www.gnu.org/licenses/gpl.html
15 *
16 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
17 * https://www.gnu.org/licenses/lgpl.html
18 *
19 * - Mozilla Public License Version 1.1 or later (the "MPL")
20 * http://www.mozilla.org/MPL/MPL-1.1.html
21 *
22 * == END LICENSE ==
23 *
24 * These functions are used by the connector.php script.
25 */
26
32function SetXmlHeaders()
33{
34 ob_end_clean();
35
36 // Prevent the browser from caching the result.
37 // Date in the past
38 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
39 // always modified
40 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
41 // HTTP/1.1
42 header('Cache-Control: no-store, no-cache, must-revalidate');
43 header('Cache-Control: post-check=0, pre-check=0', false);
44 // HTTP/1.0
45 header('Pragma: no-cache');
46
47 // Set the response format.
48 header('Content-Type: text/xml; charset=utf-8');
49}
50
59function CreateXmlHeader($command, $resourceType, $currentFolder)
60{
61 SetXmlHeaders();
62
63 // Create the XML document header.
64 echo '<?xml version="1.0" encoding="utf-8" ?>';
65
66 // Create the main "Connector" node.
67 echo '<Connector command="'.$command.'" resourceType="'.$resourceType.'">';
68
69 // Add the current folder node.
70 echo '<CurrentFolder path="'.ConvertToXmlAttribute($currentFolder).'" url="'.ConvertToXmlAttribute(GetUrlFromPath($resourceType, $currentFolder, $command)).'" />';
71
72 $GLOBALS['HeaderSent'] = true;
73}
74
80function CreateXmlFooter()
81{
82 echo '</Connector>';
83}
84
92function SendError($number, $text)
93{
94 if ($_GET['Command'] == 'FileUpload') {
95 SendUploadResults((string) $number, "", "", $text);
96 }
97
98 if (isset($GLOBALS['HeaderSent']) && $GLOBALS['HeaderSent']) {
99 SendErrorNode($number, $text);
100 CreateXmlFooter();
101 } else {
102 SetXmlHeaders();
103
104 dol_syslog('Error: '.$number.' '.$text, LOG_ERR);
105
106 // Create the XML document header
107 echo '<?xml version="1.0" encoding="utf-8" ?>';
108
109 echo '<Connector>';
110
111 SendErrorNode($number, $text);
112
113 echo '</Connector>';
114 }
115 exit;
116}
117
125function SendErrorNode($number, $text)
126{
127 if ($text) {
128 echo '<Error number="'.$number.'" text="'.htmlspecialchars($text).'" />';
129 } else {
130 echo '<Error number="'.$number.'" />';
131 }
132 return '';
133}
134
135
136
144function GetFolders($resourceType, $currentFolder)
145{
146 // Map the virtual path to the local server path.
147 $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFolders');
148
149 // Array that will hold the folders names.
150 $aFolders = array();
151
152 $oCurrentFolder = @opendir($sServerDir);
153
154 if ($oCurrentFolder !== false) {
155 while ($sFile = readdir($oCurrentFolder)) {
156 if ($sFile != '.' && $sFile != '..' && is_dir($sServerDir.$sFile)) {
157 $aFolders[] = '<Folder name="'.ConvertToXmlAttribute($sFile).'" />';
158 }
159 }
160 closedir($oCurrentFolder);
161 }
162
163 // Open the "Folders" node.
164 echo "<Folders>";
165
166 natcasesort($aFolders);
167 foreach ($aFolders as $sFolder) {
168 echo $sFolder;
169 }
170
171 // Close the "Folders" node.
172 echo "</Folders>";
173}
174
182function GetFoldersAndFiles($resourceType, $currentFolder)
183{
184 // Map the virtual path to the local server path.
185 $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFoldersAndFiles');
186
187 // Arrays that will hold the folders and files names.
188 $aFolders = array();
189 $aFiles = array();
190
191 $oCurrentFolder = @opendir($sServerDir);
192
193 if ($oCurrentFolder !== false) {
194 while ($sFile = readdir($oCurrentFolder)) {
195 if ($sFile != '.' && $sFile != '..') {
196 if (is_dir($sServerDir.$sFile)) {
197 $aFolders[] = '<Folder name="'.ConvertToXmlAttribute($sFile).'" />';
198 } else {
199 $iFileSize = @filesize($sServerDir.$sFile);
200 if (!$iFileSize) {
201 $iFileSize = 0;
202 }
203 if ($iFileSize > 0) {
204 $iFileSize = round($iFileSize / 1024);
205 if ($iFileSize < 1) {
206 $iFileSize = 1;
207 }
208 }
209
210 $aFiles[] = '<File name="'.ConvertToXmlAttribute($sFile).'" size="'.$iFileSize.'" />';
211 }
212 }
213 }
214 closedir($oCurrentFolder);
215 }
216
217 // Send the folders
218 natcasesort($aFolders);
219 echo '<Folders>';
220
221 foreach ($aFolders as $sFolder) {
222 echo $sFolder;
223 }
224
225 echo '</Folders>';
226
227 // Send the files
228 natcasesort($aFiles);
229 echo '<Files>';
230
231 foreach ($aFiles as $sFiles) {
232 echo $sFiles;
233 }
234
235 echo '</Files>';
236}
237
245function CreateFolder($resourceType, $currentFolder)
246{
247 $sErrorNumber = '0';
248 $sErrorMsg = '';
249
250 if (isset($_GET['NewFolderName'])) {
251 $sNewFolderName = GETPOST('NewFolderName');
252 $sNewFolderName = SanitizeFolderName($sNewFolderName);
253
254 if (strpos($sNewFolderName, '..') !== false) {
255 $sErrorNumber = '102'; // Invalid folder name.
256 } else {
257 // Map the virtual path to the local server path of the current folder.
258 $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'CreateFolder');
259
260 if (is_writable($sServerDir)) {
261 $sServerDir .= $sNewFolderName;
262
263 $sErrorMsg = CreateServerFolder($sServerDir);
264
265 switch ($sErrorMsg) {
266 case '':
267 $sErrorNumber = '0';
268 break;
269 case 'Invalid argument':
270 case 'No such file or directory':
271 $sErrorNumber = '102'; // Path too long.
272 break;
273 default:
274 $sErrorNumber = '110';
275 break;
276 }
277 } else {
278 $sErrorNumber = '103';
279 }
280 }
281 } else {
282 $sErrorNumber = '102';
283 }
284
285 // Create the "Error" node.
286 echo '<Error number="'.$sErrorNumber.'" />';
287}
288
298function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '')
299{
300 global $user;
301
302 if (!isset($_FILES)) {
303 global $_FILES;
304 }
305 $sErrorNumber = '0';
306 $sFileName = '';
307
308 if (isset($_FILES['NewFile']) && !is_null($_FILES['NewFile']['tmp_name']) && !is_null($_FILES['NewFile']['name']) || (isset($_FILES['upload']) && !is_null($_FILES['upload']['tmp_name']) && !is_null($_FILES['upload']['name']))) {
309 global $Config;
310
311 $oFile = isset($_FILES['NewFile']) ? $_FILES['NewFile'] : $_FILES['upload'];
312
313 // $resourceType should be 'Image';
314 $detectHtml = 0;
315
316 // Map the virtual path to the local server path.
317 $sServerDir = ServerMapFolder($resourceType, $currentFolder, $sCommand);
318
319 // Get the uploaded file name.
320 $sFileName = $oFile['name'];
321
322 //$sFileName = SanitizeFileName($sFileName);
323 $sFileName = dol_sanitizeFileName($sFileName);
324
325 $sOriginalFileName = $sFileName;
326
327 // Get the extension.
328 $sExtension = substr($sFileName, (strrpos($sFileName, '.') + 1));
329 $sExtension = strtolower($sExtension);
330
331 // Check permission
332 $permissiontouploadmediaisok = 1;
333 if (!empty($user->socid)) {
334 $permissiontouploadmediaisok = 0;
335 }
336 /*if (!$user->hasRight('website', 'write') && !$user->hasRight('mailing', 'write')) {
337 $permissiontouploadmediaisok = 0;
338 }*/
339 if (!$permissiontouploadmediaisok) {
340 dol_syslog("connector.lib.php Try to upload a file with no permission");
341 $sErrorNumber = '202';
342 }
343
344 include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
345 //var_dump($sFileName); var_dump(image_format_supported($sFileName));exit;
346 $imgsupported = image_format_supported($sFileName);
347 $isImageValid = ($imgsupported >= 0);
348 if (!$isImageValid) {
349 $sErrorNumber = '202';
350 }
351
352
353 // Check if it is an allowed extension.
354 if (!$sErrorNumber) {
355 if (IsAllowedExt($sExtension, $resourceType)) {
356 $iCounter = 0;
357
358 while (true) {
359 $sFilePath = $sServerDir.$sFileName;
360
361 if (is_file($sFilePath)) {
362 $iCounter++;
363 $sFileName = RemoveExtension($sOriginalFileName).'('.$iCounter.').'.$sExtension;
364 $sErrorNumber = '201';
365 } else {
366 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
367 dol_move_uploaded_file($oFile['tmp_name'], $sFilePath, 0, 0);
368
369 if (is_file($sFilePath)) {
370 if (isset($Config['ChmodOnUpload']) && !$Config['ChmodOnUpload']) {
371 break;
372 }
373
374 $permissions = '0777';
375 if (isset($Config['ChmodOnUpload']) && $Config['ChmodOnUpload']) {
376 $permissions = (string) $Config['ChmodOnUpload'];
377 }
378 $permissionsdec = octdec($permissions);
379 dol_syslog("connector.lib.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec));
380 $oldumask = umask(0);
381 chmod($sFilePath, $permissionsdec);
382 umask($oldumask);
383 }
384
385 break;
386 }
387 }
388
389 if (file_exists($sFilePath)) {
390 //previous checks failed, try once again
391 if (isset($isImageValid) && $imgsupported === -1 && IsImageValid($sFilePath, $sExtension) === false) {
392 dol_syslog("connector.lib.php IsImageValid is ko");
393 @unlink($sFilePath);
394 $sErrorNumber = '202';
395 } else {
396 $detectHtml = DetectHtml($sFilePath);
397 if ($detectHtml === true || $detectHtml == -1) {
398 // Note that is is a simple test and not reliable. Security does not rely on this.
399 dol_syslog("connector.lib.php DetectHtml is ko");
400 @unlink($sFilePath);
401 $sErrorNumber = '202';
402 }
403 }
404 }
405 } else {
406 $sErrorNumber = '202';
407 }
408 }
409 } else {
410 $sErrorNumber = '203';
411 }
412
413
414 $sFileUrl = CombinePaths(GetResourceTypePath($resourceType, $sCommand), $currentFolder);
415 $sFileUrl = CombinePaths($sFileUrl, $sFileName);
416
417
418 // @CHANGE
419 //SendUploadResults( $sErrorNumber, $sFileUrl, $sFileName );
420 if ($CKEcallback == '') {
421 // this line already exists so wrap the if block around it
422 SendUploadResults($sErrorNumber, $sFileUrl, $sFileName);
423 } else {
424 //issue the CKEditor Callback
425 SendCKEditorResults(
426 $CKEcallback,
427 $sFileUrl,
428 ($sErrorNumber != 0 ? 'Error '.$sErrorNumber.' upload failed.' : 'Upload Successful')
429 );
430 }
431
432 exit;
433}
434
435
436
444function CombinePaths($sBasePath, $sFolder)
445{
446 return RemoveFromEnd($sBasePath, '/').'/'.RemoveFromStart($sFolder, '/');
447}
448
456function GetResourceTypePath($resourceType, $sCommand)
457{
458 global $Config;
459
460 if ($sCommand == "QuickUpload") {
461 return $Config['QuickUploadPath'][$resourceType];
462 } else {
463 return $Config['FileTypesPath'][$resourceType];
464 }
465}
466
474function GetResourceTypeDirectory($resourceType, $sCommand)
475{
476 global $Config;
477 if ($sCommand == "QuickUpload") {
478 if (strlen($Config['QuickUploadAbsolutePath'][$resourceType]) > 0) {
479 return $Config['QuickUploadAbsolutePath'][$resourceType];
480 }
481
482 // Map the "UserFiles" path to a local directory.
483 return Server_MapPath($Config['QuickUploadPath'][$resourceType]);
484 } else {
485 if (strlen($Config['FileTypesAbsolutePath'][$resourceType]) > 0) {
486 return $Config['FileTypesAbsolutePath'][$resourceType];
487 }
488
489 // Map the "UserFiles" path to a local directory.
490 return Server_MapPath($Config['FileTypesPath'][$resourceType]);
491 }
492}
493
502function GetUrlFromPath($resourceType, $folderPath, $sCommand)
503{
504 return CombinePaths(GetResourceTypePath($resourceType, $sCommand), $folderPath);
505}
506
513function RemoveExtension($fileName)
514{
515 return substr($fileName, 0, strrpos($fileName, '.'));
516}
517
526function ServerMapFolder($resourceType, $folderPath, $sCommand)
527{
528 // Get the resource type directory.
529 $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand);
530
531 // Ensure that the directory exists.
532 $sErrorMsg = CreateServerFolder($sResourceTypePath);
533 if ($sErrorMsg != '') {
534 SendError(1, "Error creating folder \"$sResourceTypePath\" ($sErrorMsg)");
535 }
536
537 // Return the resource type directory combined with the required path.
538 return CombinePaths($sResourceTypePath, $folderPath);
539}
540
547function GetParentFolder($folderPath)
548{
549 $sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-";
550 return preg_replace($sPattern, '', $folderPath);
551}
552
560function CreateServerFolder($folderPath, $lastFolder = null)
561{
562 global $user;
563 global $Config;
564
565 $sParent = GetParentFolder($folderPath);
566
567 // Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms
568 while (strpos($folderPath, '//') !== false) {
569 $folderPath = str_replace('//', '/', $folderPath);
570 }
571
572 $permissiontouploadmediaisok = 1;
573 if (!empty($user->socid)) {
574 $permissiontouploadmediaisok = 0;
575 }
576 /*if (!$user->hasRight('website', 'write') && !$user->hasRight('mailing', 'write')) {
577 $permissiontouploadmediaisok = 0;
578 }*/
579 if (!$permissiontouploadmediaisok) {
580 return 'Bad permissions to create a folder in media directory';
581 }
582
583 // Check if the parent exists, or create it.
584 if (!empty($sParent) && !file_exists($sParent)) {
585 //prevents against infinite loop when we can't create root folder
586 if (!is_null($lastFolder) && $lastFolder === $sParent) {
587 return "Can't create $folderPath directory";
588 }
589
590 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
591 $sErrorMsg = CreateServerFolder($sParent, $folderPath);
592 if ($sErrorMsg != '') {
593 return $sErrorMsg;
594 }
595 }
596
597 if (!file_exists($folderPath)) {
598 // Turn off all error reporting.
599 error_reporting(0);
600
601 $php_errormsg = '';
602 // Enable error tracking to catch the error.
603 ini_set('track_errors', '1');
604
605 if (isset($Config['ChmodOnFolderCreate']) && !$Config['ChmodOnFolderCreate']) {
606 mkdir($folderPath);
607 } else {
608 $permissions = '0777';
609 if (isset($Config['ChmodOnFolderCreate']) && $Config['ChmodOnFolderCreate']) {
610 $permissions = (string) $Config['ChmodOnFolderCreate'];
611 }
612 $permissionsdec = octdec($permissions);
613 $permissionsdec |= octdec('0111'); // Set x bit required for directories
614 dol_syslog("connector.lib.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec));
615 // To create the folder with 0777 permissions, we need to set umask to zero.
616 $oldumask = umask(0);
617 mkdir($folderPath, $permissionsdec);
618 umask($oldumask);
619 }
620
621 $sErrorMsg = $php_errormsg;
622
623 // Restore the configurations.
624 ini_restore('track_errors');
625 ini_restore('error_reporting');
626
627 return $sErrorMsg;
628 } else {
629 return '';
630 }
631}
632
638function GetRootPath()
639{
640 if (!isset($_SERVER)) {
641 global $_SERVER;
642 }
643 $sRealPath = realpath('./');
644 // #2124 ensure that no slash is at the end
645 $sRealPath = rtrim($sRealPath, "\\/");
646
647 $sSelfPath = $_SERVER['PHP_SELF'];
648 $sSelfPath = substr($sSelfPath, 0, strrpos($sSelfPath, '/'));
649
650 $sSelfPath = str_replace('/', DIRECTORY_SEPARATOR, $sSelfPath);
651
652 $position = strpos($sRealPath, $sSelfPath);
653
654 // This can check only that this script isn't run from a virtual dir
655 // But it avoids the problems that arise if it isn't checked
656 if ($position === false || $position != strlen($sRealPath) - strlen($sSelfPath)) {
657 SendError(1, 'Sorry, can\'t map "UserFilesPath" to a physical path. You must set the "UserFilesAbsolutePath" value in "editor/filemanager/connectors/php/config.inc.php".');
658 }
659
660 return substr($sRealPath, 0, $position);
661}
662
668function Server_MapPath($path)
669{
670 // This function is available only for Apache
671 if (function_exists('apache_lookup_uri')) {
672 $info = apache_lookup_uri($path);
673 return $info->filename.$info->path_info;
674 }
675
676 // This isn't correct but for the moment there's no other solution
677 // If this script is under a virtual directory or symlink it will detect the problem and stop
678 return GetRootPath().$path;
679}
680
688function IsAllowedExt($sExtension, $resourceType)
689{
690 global $Config;
691 // Get the allowed and denied extensions arrays.
692 $arAllowed = $Config['AllowedExtensions'][$resourceType];
693 $arDenied = $Config['DeniedExtensions'][$resourceType];
694
695 if (count($arAllowed) > 0 && !in_array($sExtension, $arAllowed)) {
696 return false;
697 }
698
699 if (count($arDenied) > 0 && in_array($sExtension, $arDenied)) {
700 return false;
701 }
702
703 return true;
704}
705
712function IsAllowedType($resourceType)
713{
714 global $Config;
715 if (!in_array($resourceType, $Config['ConfigAllowedTypes'])) {
716 return false;
717 }
718
719 return true;
720}
721
728function IsAllowedCommand($sCommand)
729{
730 global $Config;
731
732 if (!in_array($sCommand, $Config['ConfigAllowedCommands'])) {
733 return false;
734 }
735
736 return true;
737}
738
744function GetCurrentFolder()
745{
746 $sCurrentFolder = isset($_GET['CurrentFolder']) ? GETPOST('CurrentFolder', 'alphanohtml', 1) : '/';
747
748 // Check the current folder syntax (must begin and start with a slash).
749 if (!preg_match('|/$|', $sCurrentFolder)) {
750 $sCurrentFolder .= '/';
751 }
752 if (strpos($sCurrentFolder, '/') !== 0) {
753 $sCurrentFolder = '/'.$sCurrentFolder;
754 }
755
756 // Ensure the folder path has no double-slashes
757 while (strpos($sCurrentFolder, '//') !== false) {
758 $sCurrentFolder = str_replace('//', '/', $sCurrentFolder);
759 }
760
761 // Check for invalid folder paths (..)
762 if (strpos($sCurrentFolder, '..') || strpos($sCurrentFolder, "\\")) {
763 SendError(102, '');
764 }
765
766 if (preg_match(",(/\.)|[[:cntrl:]]|(//)|(\\\\)|([\:\*\?\"<>\|]),", $sCurrentFolder)) {
767 SendError(102, '');
768 }
769
770 return $sCurrentFolder;
771}
772
779function SanitizeFolderName($sNewFolderName)
780{
781 $sNewFolderName = stripslashes($sNewFolderName);
782
783 // Remove . \ / | : ? * " < >
784 $sNewFolderName = preg_replace('/\\.|\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFolderName);
785
786 return $sNewFolderName;
787}
788
795function SanitizeFileName($sNewFileName)
796{
797 global $Config;
798
799 $sNewFileName = stripslashes($sNewFileName);
800
801 // Replace dots in the name with underscores (only one dot can be there... security issue).
802 if ($Config['ForceSingleExtension']) {
803 $sNewFileName = preg_replace('/\\.(?![^.]*$)/', '_', $sNewFileName);
804 }
805
806 // Remove \ / | : ? * " < >
807 $sNewFileName = preg_replace('/\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFileName);
808
809 return $sNewFileName;
810}
811
821function SendUploadResults($errorNumber, $fileUrl = '', $fileName = '', $customMsg = '')
822{
823 // Minified version of the document.domain automatic fix script (#1919).
824 // The original script can be found at _dev/domain_fix_template.js
825 echo <<<EOF
826<script type="text/javascript">
827(function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();
828EOF;
829
830 if ($errorNumber && $errorNumber != '201') {
831 $fileUrl = "";
832 $fileName = "";
833 }
834
835 $rpl = array('\\' => '\\\\', '"' => '\\"');
836 echo 'console.log('.$errorNumber.');';
837 echo 'window.parent.OnUploadCompleted('.$errorNumber.', "'.strtr($fileUrl, $rpl).'", "'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");';
838 echo '</script>';
839 exit;
840}
841
842
843// @CHANGE
844
845// This is the function that sends the results of the uploading process to CKE.
854function SendCKEditorResults($callback, $sFileUrl, $customMsg = '')
855{
856 echo '<script type="text/javascript">';
857
858 $rpl = array('\\' => '\\\\', '"' => '\\"');
859
860 echo 'window.parent.CKEDITOR.tools.callFunction("'.$callback.'","'.strtr($sFileUrl, $rpl).'", "'.strtr($customMsg, $rpl).'");';
861
862 echo '</script>';
863}
864
865
866
874function RemoveFromStart($sourceString, $charToRemove)
875{
876 $sPattern = '|^'.$charToRemove.'+|';
877 return preg_replace($sPattern, '', $sourceString);
878}
879
887function RemoveFromEnd($sourceString, $charToRemove)
888{
889 $sPattern = '|'.$charToRemove.'+$|';
890 return preg_replace($sPattern, '', $sourceString);
891}
892
899function FindBadUtf8($string)
900{
901 $regex = '([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]';
902 $regex .= '|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2}|(.{1}))';
903
904 $matches = array();
905 while (preg_match('/'.$regex.'/S', $string, $matches)) {
906 if (isset($matches[2])) {
907 return true;
908 }
909 $string = substr($string, strlen($matches[0]));
910 }
911
912 return false;
913}
914
921function ConvertToXmlAttribute($value)
922{
923 if (defined('PHP_OS')) {
924 $os = PHP_OS;
925 } else {
926 $os = php_uname();
927 }
928
929 if (strtoupper(substr($os, 0, 3)) === 'WIN' || FindBadUtf8($value)) {
930 return (mb_convert_encoding(htmlspecialchars($value), 'UTF-8', 'ISO-8859-1'));
931 } else {
932 return (htmlspecialchars($value));
933 }
934}
935
943function IsHtmlExtension($ext, $formExtensions)
944{
945 if (!$formExtensions || !is_array($formExtensions)) {
946 return false;
947 }
948 $lcaseHtmlExtensions = array();
949 foreach ($formExtensions as $key => $val) {
950 $lcaseHtmlExtensions[$key] = strtolower($val);
951 }
952 return in_array($ext, $lcaseHtmlExtensions);
953}
954
962function DetectHtml($filePath)
963{
964 $fp = @fopen($filePath, 'rb');
965
966 //open_basedir restriction, see #1906
967 if ($fp === false || !flock($fp, LOCK_SH)) {
968 return -1;
969 }
970
971 $chunk = fread($fp, 1024);
972 flock($fp, LOCK_UN);
973 fclose($fp);
974
975 $chunk = strtolower($chunk);
976
977 if (!$chunk) {
978 return false;
979 }
980
981 $chunk = trim($chunk);
982
983 if (preg_match("/<!DOCTYPE\W*X?HTML/sim", $chunk)) {
984 return true;
985 }
986
987 $tags = array('<body', '<head', '<html', '<img', '<pre', '<script', '<table', '<title');
988
989 foreach ($tags as $tag) {
990 if (false !== strpos($chunk, $tag)) {
991 return true;
992 }
993 }
994
995 //type = javascript
996 if (preg_match('!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk)) {
997 return true;
998 }
999
1000 //href = javascript
1001 //src = javascript
1002 //data = javascript
1003 if (preg_match('!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk)) {
1004 return true;
1005 }
1006
1007 //url(javascript
1008 if (preg_match('!url\s*\‍(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk)) {
1009 return true;
1010 }
1011
1012 return false;
1013}
1014
1023function IsImageValid($filePath, $extension)
1024{
1025 if (!@is_readable($filePath)) {
1026 return -1;
1027 }
1028
1029 $imageCheckExtensions = array(
1030 'gif',
1031 'jpeg',
1032 'jpg',
1033 'png',
1034 'swf',
1035 'psd',
1036 'bmp',
1037 'iff',
1038 'tiff',
1039 'tif',
1040 'swc',
1041 'jpc',
1042 'jp2',
1043 'jpx',
1044 'jb2',
1045 'xbm',
1046 'wbmp'
1047 );
1048
1049 if (!in_array($extension, $imageCheckExtensions)) {
1050 return true;
1051 }
1052
1053 if (@getimagesize($filePath) === false) {
1054 return false;
1055 }
1056
1057 return true;
1058}
This class is used to manage file upload using ajax.
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile', $upload_dir='')
Check validity of a file upload from an GUI page, and move it to its final destination.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:137