dolibarr  19.0.0-dev
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  return '';
131 }
132 
133 
134 
142 function GetFolders($resourceType, $currentFolder)
143 {
144  // Map the virtual path to the local server path.
145  $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFolders');
146 
147  // Array that will hold the folders names.
148  $aFolders = array();
149 
150  $oCurrentFolder = @opendir($sServerDir);
151 
152  if ($oCurrentFolder !== false) {
153  while ($sFile = readdir($oCurrentFolder)) {
154  if ($sFile != '.' && $sFile != '..' && is_dir($sServerDir.$sFile)) {
155  $aFolders[] = '<Folder name="'.ConvertToXmlAttribute($sFile).'" />';
156  }
157  }
158  closedir($oCurrentFolder);
159  }
160 
161  // Open the "Folders" node.
162  echo "<Folders>";
163 
164  natcasesort($aFolders);
165  foreach ($aFolders as $sFolder) {
166  echo $sFolder;
167  }
168 
169  // Close the "Folders" node.
170  echo "</Folders>";
171 }
172 
180 function GetFoldersAndFiles($resourceType, $currentFolder)
181 {
182  // Map the virtual path to the local server path.
183  $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFoldersAndFiles');
184 
185  // Arrays that will hold the folders and files names.
186  $aFolders = array();
187  $aFiles = array();
188 
189  $oCurrentFolder = @opendir($sServerDir);
190 
191  if ($oCurrentFolder !== false) {
192  while ($sFile = readdir($oCurrentFolder)) {
193  if ($sFile != '.' && $sFile != '..') {
194  if (is_dir($sServerDir.$sFile)) {
195  $aFolders[] = '<Folder name="'.ConvertToXmlAttribute($sFile).'" />';
196  } else {
197  $iFileSize = @filesize($sServerDir.$sFile);
198  if (!$iFileSize) {
199  $iFileSize = 0;
200  }
201  if ($iFileSize > 0) {
202  $iFileSize = round($iFileSize / 1024);
203  if ($iFileSize < 1) {
204  $iFileSize = 1;
205  }
206  }
207 
208  $aFiles[] = '<File name="'.ConvertToXmlAttribute($sFile).'" size="'.$iFileSize.'" />';
209  }
210  }
211  }
212  closedir($oCurrentFolder);
213  }
214 
215  // Send the folders
216  natcasesort($aFolders);
217  echo '<Folders>';
218 
219  foreach ($aFolders as $sFolder) {
220  echo $sFolder;
221  }
222 
223  echo '</Folders>';
224 
225  // Send the files
226  natcasesort($aFiles);
227  echo '<Files>';
228 
229  foreach ($aFiles as $sFiles) {
230  echo $sFiles;
231  }
232 
233  echo '</Files>';
234 }
235 
243 function CreateFolder($resourceType, $currentFolder)
244 {
245  if (!isset($_GET)) {
246  global $_GET;
247  }
248  $sErrorNumber = '0';
249  $sErrorMsg = '';
250 
251  if (isset($_GET['NewFolderName'])) {
252  $sNewFolderName = $_GET['NewFolderName'];
253  $sNewFolderName = SanitizeFolderName($sNewFolderName);
254 
255  if (strpos($sNewFolderName, '..') !== false) {
256  $sErrorNumber = '102'; // Invalid folder name.
257  } else {
258  // Map the virtual path to the local server path of the current folder.
259  $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'CreateFolder');
260 
261  if (is_writable($sServerDir)) {
262  $sServerDir .= $sNewFolderName;
263 
264  $sErrorMsg = CreateServerFolder($sServerDir);
265 
266  switch ($sErrorMsg) {
267  case '':
268  $sErrorNumber = '0';
269  break;
270  case 'Invalid argument':
271  case 'No such file or directory':
272  $sErrorNumber = '102'; // Path too long.
273  break;
274  default:
275  $sErrorNumber = '110';
276  break;
277  }
278  } else {
279  $sErrorNumber = '103';
280  }
281  }
282  } else {
283  $sErrorNumber = '102';
284  }
285 
286  // Create the "Error" node.
287  echo '<Error number="'.$sErrorNumber.'" />';
288 }
289 
299 function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '')
300 {
301  global $user;
302 
303  if (!isset($_FILES)) {
304  global $_FILES;
305  }
306  $sErrorNumber = '0';
307  $sFileName = '';
308 
309  if (isset($_FILES['NewFile']) && !is_null($_FILES['NewFile']['tmp_name']) || (isset($_FILES['upload']) && !is_null($_FILES['upload']['tmp_name']))) {
310  global $Config;
311 
312  $oFile = isset($_FILES['NewFile']) ? $_FILES['NewFile'] : $_FILES['upload'];
313 
314  // $resourceType should be 'Image';
315  $detectHtml = 0;
316 
317  // Map the virtual path to the local server path.
318  $sServerDir = ServerMapFolder($resourceType, $currentFolder, $sCommand);
319 
320  // Get the uploaded file name.
321  $sFileName = $oFile['name'];
322 
323  //$sFileName = SanitizeFileName($sFileName);
324  $sFileName = dol_sanitizeFileName($sFileName);
325 
326  $sOriginalFileName = $sFileName;
327 
328  // Get the extension.
329  $sExtension = substr($sFileName, (strrpos($sFileName, '.') + 1));
330  $sExtension = strtolower($sExtension);
331 
332  // Check permission
333  $permissiontouploadmediaisok = 1;
334  if (!empty($user->socid)) {
335  $permissiontouploadmediaisok = 0;
336  }
337  /*if (!$user->hasRight('website', 'write') && !$user->hasRight('mailing', 'write')) {
338  $permissiontouploadmediaisok = 0;
339  }*/
340  if (!$permissiontouploadmediaisok) {
341  dol_syslog("connector.lib.php Try to upload a file with no permission");
342  $sErrorNumber = '202';
343  }
344 
345  include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
346  //var_dump($sFileName); var_dump(image_format_supported($sFileName));exit;
347  $imgsupported = image_format_supported($sFileName);
348  $isImageValid = ($imgsupported >= 0 ? true : false);
349  if (!$isImageValid) {
350  $sErrorNumber = '202';
351  }
352 
353 
354  // Check if it is an allowed extension.
355  if (!$sErrorNumber) {
356  if (IsAllowedExt($sExtension, $resourceType)) {
357  $iCounter = 0;
358 
359  while (true) {
360  $sFilePath = $sServerDir.$sFileName;
361 
362  if (is_file($sFilePath)) {
363  $iCounter++;
364  $sFileName = RemoveExtension($sOriginalFileName).'('.$iCounter.').'.$sExtension;
365  $sErrorNumber = '201';
366  } else {
367  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
368  dol_move_uploaded_file($oFile['tmp_name'], $sFilePath, 0, 0);
369 
370  if (is_file($sFilePath)) {
371  if (isset($Config['ChmodOnUpload']) && !$Config['ChmodOnUpload']) {
372  break;
373  }
374 
375  $permissions = '0777';
376  if (isset($Config['ChmodOnUpload']) && $Config['ChmodOnUpload']) {
377  $permissions = (string) $Config['ChmodOnUpload'];
378  }
379  $permissionsdec = octdec($permissions);
380  dol_syslog("connector.lib.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec));
381  $oldumask = umask(0);
382  chmod($sFilePath, $permissionsdec);
383  umask($oldumask);
384  }
385 
386  break;
387  }
388  }
389 
390  if (file_exists($sFilePath)) {
391  //previous checks failed, try once again
392  if (isset($isImageValid) && $imgsupported === -1 && IsImageValid($sFilePath, $sExtension) === false) {
393  dol_syslog("connector.lib.php IsImageValid is ko");
394  @unlink($sFilePath);
395  $sErrorNumber = '202';
396  } elseif (isset($detectHtml) && $detectHtml === -1 && DetectHtml($sFilePath) === true) {
397  dol_syslog("connector.lib.php DetectHtml is ko");
398  @unlink($sFilePath);
399  $sErrorNumber = '202';
400  }
401  }
402  } else {
403  $sErrorNumber = '202';
404  }
405  }
406  } else {
407  $sErrorNumber = '203';
408  }
409 
410 
411  $sFileUrl = CombinePaths(GetResourceTypePath($resourceType, $sCommand), $currentFolder);
412  $sFileUrl = CombinePaths($sFileUrl, $sFileName);
413 
414 
415  // @CHANGE
416  //SendUploadResults( $sErrorNumber, $sFileUrl, $sFileName );
417  if ($CKEcallback == '') {
418  // this line already exists so wrap the if block around it
419  SendUploadResults($sErrorNumber, $sFileUrl, $sFileName);
420  } else {
421  //issue the CKEditor Callback
422  SendCKEditorResults(
423  $CKEcallback,
424  $sFileUrl,
425  ($sErrorNumber != 0 ? 'Error '.$sErrorNumber.' upload failed.' : 'Upload Successful')
426  );
427  }
428 
429  exit;
430 }
431 
432 
433 
441 function CombinePaths($sBasePath, $sFolder)
442 {
443  return RemoveFromEnd($sBasePath, '/').'/'.RemoveFromStart($sFolder, '/');
444 }
445 
453 function GetResourceTypePath($resourceType, $sCommand)
454 {
455  global $Config;
456 
457  if ($sCommand == "QuickUpload") {
458  return $Config['QuickUploadPath'][$resourceType];
459  } else {
460  return $Config['FileTypesPath'][$resourceType];
461  }
462 }
463 
471 function GetResourceTypeDirectory($resourceType, $sCommand)
472 {
473  global $Config;
474  if ($sCommand == "QuickUpload") {
475  if (strlen($Config['QuickUploadAbsolutePath'][$resourceType]) > 0) {
476  return $Config['QuickUploadAbsolutePath'][$resourceType];
477  }
478 
479  // Map the "UserFiles" path to a local directory.
480  return Server_MapPath($Config['QuickUploadPath'][$resourceType]);
481  } else {
482  if (strlen($Config['FileTypesAbsolutePath'][$resourceType]) > 0) {
483  return $Config['FileTypesAbsolutePath'][$resourceType];
484  }
485 
486  // Map the "UserFiles" path to a local directory.
487  return Server_MapPath($Config['FileTypesPath'][$resourceType]);
488  }
489 }
490 
499 function GetUrlFromPath($resourceType, $folderPath, $sCommand)
500 {
501  return CombinePaths(GetResourceTypePath($resourceType, $sCommand), $folderPath);
502 }
503 
510 function RemoveExtension($fileName)
511 {
512  return substr($fileName, 0, strrpos($fileName, '.'));
513 }
514 
523 function ServerMapFolder($resourceType, $folderPath, $sCommand)
524 {
525  // Get the resource type directory.
526  $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand);
527 
528  // Ensure that the directory exists.
529  $sErrorMsg = CreateServerFolder($sResourceTypePath);
530  if ($sErrorMsg != '') {
531  SendError(1, "Error creating folder \"$sResourceTypePath\" ($sErrorMsg)");
532  }
533 
534  // Return the resource type directory combined with the required path.
535  return CombinePaths($sResourceTypePath, $folderPath);
536 }
537 
544 function GetParentFolder($folderPath)
545 {
546  $sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-";
547  return preg_replace($sPattern, '', $folderPath);
548 }
549 
557 function CreateServerFolder($folderPath, $lastFolder = null)
558 {
559  global $user;
560  global $Config;
561 
562  $sParent = GetParentFolder($folderPath);
563 
564  // Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms
565  while (strpos($folderPath, '//') !== false) {
566  $folderPath = str_replace('//', '/', $folderPath);
567  }
568 
569  $permissiontouploadmediaisok = 1;
570  if (!empty($user->socid)) {
571  $permissiontouploadmediaisok = 0;
572  }
573  /*if (!$user->hasRight('website', 'write') && !$user->hasRight('mailing', 'write')) {
574  $permissiontouploadmediaisok = 0;
575  }*/
576  if (!$permissiontouploadmediaisok) {
577  return 'Bad permissions to create a folder in media directory';
578  }
579 
580  // Check if the parent exists, or create it.
581  if (!empty($sParent) && !file_exists($sParent)) {
582  //prevents agains infinite loop when we can't create root folder
583  if (!is_null($lastFolder) && $lastFolder === $sParent) {
584  return "Can't create $folderPath directory";
585  }
586 
587  $sErrorMsg = CreateServerFolder($sParent, $folderPath);
588  if ($sErrorMsg != '') {
589  return $sErrorMsg;
590  }
591  }
592 
593  if (!file_exists($folderPath)) {
594  // Turn off all error reporting.
595  error_reporting(0);
596 
597  $php_errormsg = '';
598  // Enable error tracking to catch the error.
599  ini_set('track_errors', '1');
600 
601  if (isset($Config['ChmodOnFolderCreate']) && !$Config['ChmodOnFolderCreate']) {
602  mkdir($folderPath);
603  } else {
604  $permissions = '0777';
605  if (isset($Config['ChmodOnFolderCreate']) && $Config['ChmodOnFolderCreate']) {
606  $permissions = (string) $Config['ChmodOnFolderCreate'];
607  }
608  $permissionsdec = octdec($permissions);
609  $permissionsdec |= octdec('0111'); // Set x bit required for directories
610  dol_syslog("connector.lib.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec));
611  // To create the folder with 0777 permissions, we need to set umask to zero.
612  $oldumask = umask(0);
613  mkdir($folderPath, $permissionsdec);
614  umask($oldumask);
615  }
616 
617  $sErrorMsg = $php_errormsg;
618 
619  // Restore the configurations.
620  ini_restore('track_errors');
621  ini_restore('error_reporting');
622 
623  return $sErrorMsg;
624  } else {
625  return '';
626  }
627 }
628 
634 function GetRootPath()
635 {
636  if (!isset($_SERVER)) {
637  global $_SERVER;
638  }
639  $sRealPath = realpath('./');
640  // #2124 ensure that no slash is at the end
641  $sRealPath = rtrim($sRealPath, "\\/");
642 
643  $sSelfPath = $_SERVER['PHP_SELF'];
644  $sSelfPath = substr($sSelfPath, 0, strrpos($sSelfPath, '/'));
645 
646  $sSelfPath = str_replace('/', DIRECTORY_SEPARATOR, $sSelfPath);
647 
648  $position = strpos($sRealPath, $sSelfPath);
649 
650  // This can check only that this script isn't run from a virtual dir
651  // But it avoids the problems that arise if it isn't checked
652  if ($position === false || $position <> strlen($sRealPath) - strlen($sSelfPath)) {
653  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".');
654  }
655 
656  return substr($sRealPath, 0, $position);
657 }
658 
664 function Server_MapPath($path)
665 {
666  // This function is available only for Apache
667  if (function_exists('apache_lookup_uri')) {
668  $info = apache_lookup_uri($path);
669  return $info->filename.$info->path_info;
670  }
671 
672  // This isn't correct but for the moment there's no other solution
673  // If this script is under a virtual directory or symlink it will detect the problem and stop
674  return GetRootPath().$path;
675 }
676 
684 function IsAllowedExt($sExtension, $resourceType)
685 {
686  global $Config;
687  // Get the allowed and denied extensions arrays.
688  $arAllowed = $Config['AllowedExtensions'][$resourceType];
689  $arDenied = $Config['DeniedExtensions'][$resourceType];
690 
691  if (count($arAllowed) > 0 && !in_array($sExtension, $arAllowed)) {
692  return false;
693  }
694 
695  if (count($arDenied) > 0 && in_array($sExtension, $arDenied)) {
696  return false;
697  }
698 
699  return true;
700 }
701 
708 function IsAllowedType($resourceType)
709 {
710  global $Config;
711  if (!in_array($resourceType, $Config['ConfigAllowedTypes'])) {
712  return false;
713  }
714 
715  return true;
716 }
717 
724 function IsAllowedCommand($sCommand)
725 {
726  global $Config;
727 
728  if (!in_array($sCommand, $Config['ConfigAllowedCommands'])) {
729  return false;
730  }
731 
732  return true;
733 }
734 
740 function GetCurrentFolder()
741 {
742  if (!isset($_GET)) {
743  global $_GET;
744  }
745  $sCurrentFolder = isset($_GET['CurrentFolder']) ? GETPOST('CurrentFolder', '', 1) : '/';
746 
747  // Check the current folder syntax (must begin and start with a slash).
748  if (!preg_match('|/$|', $sCurrentFolder)) {
749  $sCurrentFolder .= '/';
750  }
751  if (strpos($sCurrentFolder, '/') !== 0) {
752  $sCurrentFolder = '/'.$sCurrentFolder;
753  }
754 
755  // Ensure the folder path has no double-slashes
756  while (strpos($sCurrentFolder, '//') !== false) {
757  $sCurrentFolder = str_replace('//', '/', $sCurrentFolder);
758  }
759 
760  // Check for invalid folder paths (..)
761  if (strpos($sCurrentFolder, '..') || strpos($sCurrentFolder, "\\")) {
762  SendError(102, '');
763  }
764 
765  if (preg_match(",(/\.)|[[:cntrl:]]|(//)|(\\\\)|([\:\*\?\"<>\|]),", $sCurrentFolder)) {
766  SendError(102, '');
767  }
768 
769  return $sCurrentFolder;
770 }
771 
778 function SanitizeFolderName($sNewFolderName)
779 {
780  $sNewFolderName = stripslashes($sNewFolderName);
781 
782  // Remove . \ / | : ? * " < >
783  $sNewFolderName = preg_replace('/\\.|\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFolderName);
784 
785  return $sNewFolderName;
786 }
787 
794 function SanitizeFileName($sNewFileName)
795 {
796  global $Config;
797 
798  $sNewFileName = stripslashes($sNewFileName);
799 
800  // Replace dots in the name with underscores (only one dot can be there... security issue).
801  if ($Config['ForceSingleExtension']) {
802  $sNewFileName = preg_replace('/\\.(?![^.]*$)/', '_', $sNewFileName);
803  }
804 
805  // Remove \ / | : ? * " < >
806  $sNewFileName = preg_replace('/\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFileName);
807 
808  return $sNewFileName;
809 }
810 
820 function SendUploadResults($errorNumber, $fileUrl = '', $fileName = '', $customMsg = '')
821 {
822  // Minified version of the document.domain automatic fix script (#1919).
823  // The original script can be found at _dev/domain_fix_template.js
824  echo <<<EOF
825 <script type="text/javascript">
826 (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;}}})();
827 EOF;
828 
829  if ($errorNumber && $errorNumber != 201) {
830  $fileUrl = "";
831  $fileName = "";
832  }
833 
834  $rpl = array('\\' => '\\\\', '"' => '\\"');
835  echo 'console.log('.$errorNumber.');';
836  echo 'window.parent.OnUploadCompleted('.$errorNumber.', "'.strtr($fileUrl, $rpl).'", "'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");';
837  echo '</script>';
838  exit;
839 }
840 
841 
842 // @CHANGE
843 
844 // This is the function that sends the results of the uploading process to CKE.
853 function SendCKEditorResults($callback, $sFileUrl, $customMsg = '')
854 {
855  echo '<script type="text/javascript">';
856 
857  $rpl = array('\\' => '\\\\', '"' => '\\"');
858 
859  echo 'window.parent.CKEDITOR.tools.callFunction("'.$callback.'","'.strtr($sFileUrl, $rpl).'", "'.strtr($customMsg, $rpl).'");';
860 
861  echo '</script>';
862 }
863 
864 
865 
873 function RemoveFromStart($sourceString, $charToRemove)
874 {
875  $sPattern = '|^'.$charToRemove.'+|';
876  return preg_replace($sPattern, '', $sourceString);
877 }
878 
886 function RemoveFromEnd($sourceString, $charToRemove)
887 {
888  $sPattern = '|'.$charToRemove.'+$|';
889  return preg_replace($sPattern, '', $sourceString);
890 }
891 
898 function FindBadUtf8($string)
899 {
900  $regex = '([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]';
901  $regex .= '|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2}|(.{1}))';
902 
903  $matches = array();
904  while (preg_match('/'.$regex.'/S', $string, $matches)) {
905  if (isset($matches[2])) {
906  return true;
907  }
908  $string = substr($string, strlen($matches[0]));
909  }
910 
911  return false;
912 }
913 
920 function ConvertToXmlAttribute($value)
921 {
922  if (defined('PHP_OS')) {
923  $os = PHP_OS;
924  } else {
925  $os = php_uname();
926  }
927 
928  if (strtoupper(substr($os, 0, 3)) === 'WIN' || FindBadUtf8($value)) {
929  return (utf8_encode(htmlspecialchars($value)));
930  } else {
931  return (htmlspecialchars($value));
932  }
933 }
934 
942 function IsHtmlExtension($ext, $formExtensions)
943 {
944  if (!$formExtensions || !is_array($formExtensions)) {
945  return false;
946  }
947  $lcaseHtmlExtensions = array();
948  foreach ($formExtensions as $key => $val) {
949  $lcaseHtmlExtensions[$key] = strtolower($val);
950  }
951  return in_array($ext, $lcaseHtmlExtensions);
952 }
953 
962 function 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 
1024 function IsImageValid($filePath, $extension)
1025 {
1026  if (!@is_readable($filePath)) {
1027  return -1;
1028  }
1029 
1030  $imageCheckExtensions = array(
1031  'gif',
1032  'jpeg',
1033  'jpg',
1034  'png',
1035  'swf',
1036  'psd',
1037  'bmp',
1038  'iff',
1039  'tiff',
1040  'tif',
1041  'swc',
1042  'jpc',
1043  'jp2',
1044  'jpx',
1045  'jb2',
1046  'xbm',
1047  'wbmp'
1048  );
1049 
1050  if (!in_array($extension, $imageCheckExtensions)) {
1051  return true;
1052  }
1053 
1054  if (@getimagesize($filePath) === false) {
1055  return false;
1056  }
1057 
1058  return true;
1059 }
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:1196
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:120