dolibarr  17.0.4
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  *
6  * == BEGIN LICENSE ==
7  *
8  * Licensed under the terms of any of the following licenses at your
9  * choice:
10  *
11  * - GNU General Public License Version 2 or later (the "GPL")
12  * https://www.gnu.org/licenses/gpl.html
13  *
14  * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
15  * https://www.gnu.org/licenses/lgpl.html
16  *
17  * - Mozilla Public License Version 1.1 or later (the "MPL")
18  * http://www.mozilla.org/MPL/MPL-1.1.html
19  *
20  * == END LICENSE ==
21  *
22  * These functions are used by the connector.php script.
23  */
24 
30 function SetXmlHeaders()
31 {
32  ob_end_clean();
33 
34  // Prevent the browser from caching the result.
35  // Date in the past
36  header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
37  // always modified
38  header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
39  // HTTP/1.1
40  header('Cache-Control: no-store, no-cache, must-revalidate');
41  header('Cache-Control: post-check=0, pre-check=0', false);
42  // HTTP/1.0
43  header('Pragma: no-cache');
44 
45  // Set the response format.
46  header('Content-Type: text/xml; charset=utf-8');
47 }
48 
57 function CreateXmlHeader($command, $resourceType, $currentFolder)
58 {
59  SetXmlHeaders();
60 
61  // Create the XML document header.
62  echo '<?xml version="1.0" encoding="utf-8" ?>';
63 
64  // Create the main "Connector" node.
65  echo '<Connector command="'.$command.'" resourceType="'.$resourceType.'">';
66 
67  // Add the current folder node.
68  echo '<CurrentFolder path="'.ConvertToXmlAttribute($currentFolder).'" url="'.ConvertToXmlAttribute(GetUrlFromPath($resourceType, $currentFolder, $command)).'" />';
69 
70  $GLOBALS['HeaderSent'] = true;
71 }
72 
78 function CreateXmlFooter()
79 {
80  echo '</Connector>';
81 }
82 
90 function SendError($number, $text)
91 {
92  if ($_GET['Command'] == 'FileUpload') {
93  SendUploadResults($number, "", "", $text);
94  }
95 
96  if (isset($GLOBALS['HeaderSent']) && $GLOBALS['HeaderSent']) {
97  SendErrorNode($number, $text);
98  CreateXmlFooter();
99  } else {
100  SetXmlHeaders();
101 
102  dol_syslog('Error: '.$number.' '.$text, LOG_ERR);
103 
104  // Create the XML document header
105  echo '<?xml version="1.0" encoding="utf-8" ?>';
106 
107  echo '<Connector>';
108 
109  SendErrorNode($number, $text);
110 
111  echo '</Connector>';
112  }
113  exit;
114 }
115 
123 function SendErrorNode($number, $text)
124 {
125  if ($text) {
126  echo '<Error number="'.$number.'" text="'.htmlspecialchars($text).'" />';
127  } else {
128  echo '<Error number="'.$number.'" />';
129  }
130 }
131 
132 
133 
141 function GetFolders($resourceType, $currentFolder)
142 {
143  // Map the virtual path to the local server path.
144  $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFolders');
145 
146  // Array that will hold the folders names.
147  $aFolders = array();
148 
149  $oCurrentFolder = @opendir($sServerDir);
150 
151  if ($oCurrentFolder !== false) {
152  while ($sFile = readdir($oCurrentFolder)) {
153  if ($sFile != '.' && $sFile != '..' && is_dir($sServerDir.$sFile)) {
154  $aFolders[] = '<Folder name="'.ConvertToXmlAttribute($sFile).'" />';
155  }
156  }
157  closedir($oCurrentFolder);
158  }
159 
160  // Open the "Folders" node.
161  echo "<Folders>";
162 
163  natcasesort($aFolders);
164  foreach ($aFolders as $sFolder) {
165  echo $sFolder;
166  }
167 
168  // Close the "Folders" node.
169  echo "</Folders>";
170 }
171 
179 function GetFoldersAndFiles($resourceType, $currentFolder)
180 {
181  // Map the virtual path to the local server path.
182  $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFoldersAndFiles');
183 
184  // Arrays that will hold the folders and files names.
185  $aFolders = array();
186  $aFiles = array();
187 
188  $oCurrentFolder = @opendir($sServerDir);
189 
190  if ($oCurrentFolder !== false) {
191  while ($sFile = readdir($oCurrentFolder)) {
192  if ($sFile != '.' && $sFile != '..') {
193  if (is_dir($sServerDir.$sFile)) {
194  $aFolders[] = '<Folder name="'.ConvertToXmlAttribute($sFile).'" />';
195  } else {
196  $iFileSize = @filesize($sServerDir.$sFile);
197  if (!$iFileSize) {
198  $iFileSize = 0;
199  }
200  if ($iFileSize > 0) {
201  $iFileSize = round($iFileSize / 1024);
202  if ($iFileSize < 1) {
203  $iFileSize = 1;
204  }
205  }
206 
207  $aFiles[] = '<File name="'.ConvertToXmlAttribute($sFile).'" size="'.$iFileSize.'" />';
208  }
209  }
210  }
211  closedir($oCurrentFolder);
212  }
213 
214  // Send the folders
215  natcasesort($aFolders);
216  echo '<Folders>';
217 
218  foreach ($aFolders as $sFolder) {
219  echo $sFolder;
220  }
221 
222  echo '</Folders>';
223 
224  // Send the files
225  natcasesort($aFiles);
226  echo '<Files>';
227 
228  foreach ($aFiles as $sFiles) {
229  echo $sFiles;
230  }
231 
232  echo '</Files>';
233 }
234 
242 function CreateFolder($resourceType, $currentFolder)
243 {
244  if (!isset($_GET)) {
245  global $_GET;
246  }
247  $sErrorNumber = '0';
248  $sErrorMsg = '';
249 
250  if (isset($_GET['NewFolderName'])) {
251  $sNewFolderName = $_GET['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 
298 function 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']) || (isset($_FILES['upload']) && !is_null($_FILES['upload']['tmp_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 ? true : false);
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  } elseif (isset($detectHtml) && $detectHtml === -1 && DetectHtml($sFilePath) === true) {
396  dol_syslog("connector.lib.php DetectHtml is ko");
397  @unlink($sFilePath);
398  $sErrorNumber = '202';
399  }
400  }
401  } else {
402  $sErrorNumber = '202';
403  }
404  }
405  } else {
406  $sErrorNumber = '203';
407  }
408 
409 
410  $sFileUrl = CombinePaths(GetResourceTypePath($resourceType, $sCommand), $currentFolder);
411  $sFileUrl = CombinePaths($sFileUrl, $sFileName);
412 
413 
414  // @CHANGE
415  //SendUploadResults( $sErrorNumber, $sFileUrl, $sFileName );
416  if ($CKEcallback == '') {
417  // this line already exists so wrap the if block around it
418  SendUploadResults($sErrorNumber, $sFileUrl, $sFileName);
419  } else {
420  //issue the CKEditor Callback
421  SendCKEditorResults(
422  $CKEcallback,
423  $sFileUrl,
424  ($sErrorNumber != 0 ? 'Error '.$sErrorNumber.' upload failed.' : 'Upload Successful')
425  );
426  }
427 
428  exit;
429 }
430 
431 
432 
440 function CombinePaths($sBasePath, $sFolder)
441 {
442  return RemoveFromEnd($sBasePath, '/').'/'.RemoveFromStart($sFolder, '/');
443 }
444 
452 function GetResourceTypePath($resourceType, $sCommand)
453 {
454  global $Config;
455 
456  if ($sCommand == "QuickUpload") {
457  return $Config['QuickUploadPath'][$resourceType];
458  } else {
459  return $Config['FileTypesPath'][$resourceType];
460  }
461 }
462 
470 function GetResourceTypeDirectory($resourceType, $sCommand)
471 {
472  global $Config;
473  if ($sCommand == "QuickUpload") {
474  if (strlen($Config['QuickUploadAbsolutePath'][$resourceType]) > 0) {
475  return $Config['QuickUploadAbsolutePath'][$resourceType];
476  }
477 
478  // Map the "UserFiles" path to a local directory.
479  return Server_MapPath($Config['QuickUploadPath'][$resourceType]);
480  } else {
481  if (strlen($Config['FileTypesAbsolutePath'][$resourceType]) > 0) {
482  return $Config['FileTypesAbsolutePath'][$resourceType];
483  }
484 
485  // Map the "UserFiles" path to a local directory.
486  return Server_MapPath($Config['FileTypesPath'][$resourceType]);
487  }
488 }
489 
498 function GetUrlFromPath($resourceType, $folderPath, $sCommand)
499 {
500  return CombinePaths(GetResourceTypePath($resourceType, $sCommand), $folderPath);
501 }
502 
509 function RemoveExtension($fileName)
510 {
511  return substr($fileName, 0, strrpos($fileName, '.'));
512 }
513 
522 function ServerMapFolder($resourceType, $folderPath, $sCommand)
523 {
524  // Get the resource type directory.
525  $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand);
526 
527  // Ensure that the directory exists.
528  $sErrorMsg = CreateServerFolder($sResourceTypePath);
529  if ($sErrorMsg != '') {
530  SendError(1, "Error creating folder \"{$sResourceTypePath}\" ({$sErrorMsg})");
531  }
532 
533  // Return the resource type directory combined with the required path.
534  return CombinePaths($sResourceTypePath, $folderPath);
535 }
536 
543 function GetParentFolder($folderPath)
544 {
545  $sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-";
546  return preg_replace($sPattern, '', $folderPath);
547 }
548 
556 function CreateServerFolder($folderPath, $lastFolder = null)
557 {
558  global $user;
559  global $Config;
560 
561  $sParent = GetParentFolder($folderPath);
562 
563  // Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms
564  while (strpos($folderPath, '//') !== false) {
565  $folderPath = str_replace('//', '/', $folderPath);
566  }
567 
568  $permissiontouploadmediaisok = 1;
569  if (!empty($user->socid)) {
570  $permissiontouploadmediaisok = 0;
571  }
572  /*if (!$user->hasRight('website', 'write') && !$user->hasRight('mailing', 'write')) {
573  $permissiontouploadmediaisok = 0;
574  }*/
575  if (!$permissiontouploadmediaisok) {
576  return 'Bad permissions to create a folder in media directory';
577  }
578 
579  // Check if the parent exists, or create it.
580  if (!empty($sParent) && !file_exists($sParent)) {
581  //prevents agains infinite loop when we can't create root folder
582  if (!is_null($lastFolder) && $lastFolder === $sParent) {
583  return "Can't create $folderPath directory";
584  }
585 
586  $sErrorMsg = CreateServerFolder($sParent, $folderPath);
587  if ($sErrorMsg != '') {
588  return $sErrorMsg;
589  }
590  }
591 
592  if (!file_exists($folderPath)) {
593  // Turn off all error reporting.
594  error_reporting(0);
595 
596  $php_errormsg = '';
597  // Enable error tracking to catch the error.
598  ini_set('track_errors', '1');
599 
600  if (isset($Config['ChmodOnFolderCreate']) && !$Config['ChmodOnFolderCreate']) {
601  mkdir($folderPath);
602  } else {
603  $permissions = '0777';
604  if (isset($Config['ChmodOnFolderCreate']) && $Config['ChmodOnFolderCreate']) {
605  $permissions = (string) $Config['ChmodOnFolderCreate'];
606  }
607  $permissionsdec = octdec($permissions);
608  $permissionsdec |= octdec('0111'); // Set x bit required for directories
609  dol_syslog("connector.lib.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec));
610  // To create the folder with 0777 permissions, we need to set umask to zero.
611  $oldumask = umask(0);
612  mkdir($folderPath, $permissionsdec);
613  umask($oldumask);
614  }
615 
616  $sErrorMsg = $php_errormsg;
617 
618  // Restore the configurations.
619  ini_restore('track_errors');
620  ini_restore('error_reporting');
621 
622  return $sErrorMsg;
623  } else {
624  return '';
625  }
626 }
627 
633 function GetRootPath()
634 {
635  if (!isset($_SERVER)) {
636  global $_SERVER;
637  }
638  $sRealPath = realpath('./');
639  // #2124 ensure that no slash is at the end
640  $sRealPath = rtrim($sRealPath, "\\/");
641 
642  $sSelfPath = $_SERVER['PHP_SELF'];
643  $sSelfPath = substr($sSelfPath, 0, strrpos($sSelfPath, '/'));
644 
645  $sSelfPath = str_replace('/', DIRECTORY_SEPARATOR, $sSelfPath);
646 
647  $position = strpos($sRealPath, $sSelfPath);
648 
649  // This can check only that this script isn't run from a virtual dir
650  // But it avoids the problems that arise if it isn't checked
651  if ($position === false || $position <> strlen($sRealPath) - strlen($sSelfPath)) {
652  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".');
653  }
654 
655  return substr($sRealPath, 0, $position);
656 }
657 
663 function Server_MapPath($path)
664 {
665  // This function is available only for Apache
666  if (function_exists('apache_lookup_uri')) {
667  $info = apache_lookup_uri($path);
668  return $info->filename.$info->path_info;
669  }
670 
671  // This isn't correct but for the moment there's no other solution
672  // If this script is under a virtual directory or symlink it will detect the problem and stop
673  return GetRootPath().$path;
674 }
675 
683 function IsAllowedExt($sExtension, $resourceType)
684 {
685  global $Config;
686  // Get the allowed and denied extensions arrays.
687  $arAllowed = $Config['AllowedExtensions'][$resourceType];
688  $arDenied = $Config['DeniedExtensions'][$resourceType];
689 
690  if (count($arAllowed) > 0 && !in_array($sExtension, $arAllowed)) {
691  return false;
692  }
693 
694  if (count($arDenied) > 0 && in_array($sExtension, $arDenied)) {
695  return false;
696  }
697 
698  return true;
699 }
700 
707 function IsAllowedType($resourceType)
708 {
709  global $Config;
710  if (!in_array($resourceType, $Config['ConfigAllowedTypes'])) {
711  return false;
712  }
713 
714  return true;
715 }
716 
723 function IsAllowedCommand($sCommand)
724 {
725  global $Config;
726 
727  if (!in_array($sCommand, $Config['ConfigAllowedCommands'])) {
728  return false;
729  }
730 
731  return true;
732 }
733 
739 function GetCurrentFolder()
740 {
741  if (!isset($_GET)) {
742  global $_GET;
743  }
744  $sCurrentFolder = isset($_GET['CurrentFolder']) ? GETPOST('CurrentFolder', '', 1) : '/';
745 
746  // Check the current folder syntax (must begin and start with a slash).
747  if (!preg_match('|/$|', $sCurrentFolder)) {
748  $sCurrentFolder .= '/';
749  }
750  if (strpos($sCurrentFolder, '/') !== 0) {
751  $sCurrentFolder = '/'.$sCurrentFolder;
752  }
753 
754  // Ensure the folder path has no double-slashes
755  while (strpos($sCurrentFolder, '//') !== false) {
756  $sCurrentFolder = str_replace('//', '/', $sCurrentFolder);
757  }
758 
759  // Check for invalid folder paths (..)
760  if (strpos($sCurrentFolder, '..') || strpos($sCurrentFolder, "\\")) {
761  SendError(102, '');
762  }
763 
764  if (preg_match(",(/\.)|[[:cntrl:]]|(//)|(\\\\)|([\:\*\?\"<>\|]),", $sCurrentFolder)) {
765  SendError(102, '');
766  }
767 
768  return $sCurrentFolder;
769 }
770 
777 function SanitizeFolderName($sNewFolderName)
778 {
779  $sNewFolderName = stripslashes($sNewFolderName);
780 
781  // Remove . \ / | : ? * " < >
782  $sNewFolderName = preg_replace('/\\.|\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFolderName);
783 
784  return $sNewFolderName;
785 }
786 
793 function SanitizeFileName($sNewFileName)
794 {
795  global $Config;
796 
797  $sNewFileName = stripslashes($sNewFileName);
798 
799  // Replace dots in the name with underscores (only one dot can be there... security issue).
800  if ($Config['ForceSingleExtension']) {
801  $sNewFileName = preg_replace('/\\.(?![^.]*$)/', '_', $sNewFileName);
802  }
803 
804  // Remove \ / | : ? * " < >
805  $sNewFileName = preg_replace('/\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFileName);
806 
807  return $sNewFileName;
808 }
809 
819 function SendUploadResults($errorNumber, $fileUrl = '', $fileName = '', $customMsg = '')
820 {
821  // Minified version of the document.domain automatic fix script (#1919).
822  // The original script can be found at _dev/domain_fix_template.js
823  echo <<<EOF
824 <script type="text/javascript">
825 (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;}}})();
826 EOF;
827 
828  if ($errorNumber && $errorNumber != 201) {
829  $fileUrl = "";
830  $fileName = "";
831  }
832 
833  $rpl = array('\\' => '\\\\', '"' => '\\"');
834  echo 'console.log('.$errorNumber.');';
835  echo 'window.parent.OnUploadCompleted('.$errorNumber.', "'.strtr($fileUrl, $rpl).'", "'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");';
836  echo '</script>';
837  exit;
838 }
839 
840 
841 // @CHANGE
842 
843 // This is the function that sends the results of the uploading process to CKE.
852 function SendCKEditorResults($callback, $sFileUrl, $customMsg = '')
853 {
854  echo '<script type="text/javascript">';
855 
856  $rpl = array('\\' => '\\\\', '"' => '\\"');
857 
858  echo 'window.parent.CKEDITOR.tools.callFunction("'.$callback.'","'.strtr($sFileUrl, $rpl).'", "'.strtr($customMsg, $rpl).'");';
859 
860  echo '</script>';
861 }
862 
863 
864 
872 function RemoveFromStart($sourceString, $charToRemove)
873 {
874  $sPattern = '|^'.$charToRemove.'+|';
875  return preg_replace($sPattern, '', $sourceString);
876 }
877 
885 function RemoveFromEnd($sourceString, $charToRemove)
886 {
887  $sPattern = '|'.$charToRemove.'+$|';
888  return preg_replace($sPattern, '', $sourceString);
889 }
890 
897 function FindBadUtf8($string)
898 {
899  $regex = '([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]';
900  $regex .= '|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2}|(.{1}))';
901 
902  $matches = array();
903  while (preg_match('/'.$regex.'/S', $string, $matches)) {
904  if (isset($matches[2])) {
905  return true;
906  }
907  $string = substr($string, strlen($matches[0]));
908  }
909 
910  return false;
911 }
912 
919 function ConvertToXmlAttribute($value)
920 {
921  if (defined('PHP_OS')) {
922  $os = PHP_OS;
923  } else {
924  $os = php_uname();
925  }
926 
927  if (strtoupper(substr($os, 0, 3)) === 'WIN' || FindBadUtf8($value)) {
928  return (utf8_encode(htmlspecialchars($value)));
929  } else {
930  return (htmlspecialchars($value));
931  }
932 }
933 
941 function IsHtmlExtension($ext, $formExtensions)
942 {
943  if (!$formExtensions || !is_array($formExtensions)) {
944  return false;
945  }
946  $lcaseHtmlExtensions = array();
947  foreach ($formExtensions as $key => $val) {
948  $lcaseHtmlExtensions[$key] = strtolower($val);
949  }
950  return in_array($ext, $lcaseHtmlExtensions);
951 }
952 
961 function DetectHtml($filePath)
962 {
963  $fp = @fopen($filePath, 'rb');
964 
965  //open_basedir restriction, see #1906
966  if ($fp === false || !flock($fp, LOCK_SH)) {
967  return -1;
968  }
969 
970  $chunk = fread($fp, 1024);
971  flock($fp, LOCK_UN);
972  fclose($fp);
973 
974  $chunk = strtolower($chunk);
975 
976  if (!$chunk) {
977  return false;
978  }
979 
980  $chunk = trim($chunk);
981 
982  if (preg_match("/<!DOCTYPE\W*X?HTML/sim", $chunk)) {
983  return true;
984  }
985 
986  $tags = array('<body', '<head', '<html', '<img', '<pre', '<script', '<table', '<title');
987 
988  foreach ($tags as $tag) {
989  if (false !== strpos($chunk, $tag)) {
990  return true;
991  }
992  }
993 
994  //type = javascript
995  if (preg_match('!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk)) {
996  return true;
997  }
998 
999  //href = javascript
1000  //src = javascript
1001  //data = javascript
1002  if (preg_match('!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk)) {
1003  return true;
1004  }
1005 
1006  //url(javascript
1007  if (preg_match('!url\s*\‍(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk)) {
1008  return true;
1009  }
1010 
1011  return false;
1012 }
1013 
1023 function 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='')
Make control on an uploaded file from an GUI page and move it to final destination.
Definition: files.lib.php:1112
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.
Definition: images.lib.php:80
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119