4 * Function to check and/or sanitize things for security such as
5 * directories names, file names, etc.
6 * Also including csrf token management functions.
9 * @link https://www.open-emr.org
10 * @author Brady Miller <brady.g.miller@gmail.com>
11 * @author Roberto Vasquez <robertogagliotta@gmail.com>
12 * @author Shachar Zilbershlag <shaharzi@matrix.co.il>
13 * @copyright Copyright (c) 2012-2018 Brady Miller <brady.g.miller@gmail.com>
14 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17 use OpenEMR\Events\Core\Sanitize\IsAcceptedFileFilterEvent
;
19 // Function to collect ip address(es)
20 function collectIpAddresses()
22 $mainIp = $_SERVER['REMOTE_ADDR'];
25 if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
26 $forwardIp = $_SERVER['HTTP_X_FORWARDED_FOR'];
27 $stringIp .= " (" . $forwardIp . ")";
31 'ip_string' => $stringIp,
33 'forward_ip' => $forwardIp ??
''
37 // Sanitize a json encoded entry.
38 function json_sanitize($json)
40 if (json_decode($json)) {
41 return json_encode(json_decode($json, true));
43 error_log("OPENEMR ERROR: " . errorLogEscape($json) . " is not a valid json ");
48 // If the label contains any illegal characters, then the script will die.
49 function check_file_dir_name($label)
51 if (empty($label) ||
preg_match('/[^A-Za-z0-9_.-]/', $label)) {
52 error_log("ERROR: The following variable contains invalid characters:" . errorLogEscape($label));
53 die(xlt("ERROR: The following variable contains invalid characters") . ": " . attr($label));
59 // Convert all illegal characters to _
60 function convert_safe_file_dir_name($label)
62 return preg_replace('/[^A-Za-z0-9_.-]/', '_', $label);
65 // Convert all non A-Z a-z 0-9 characters to _
66 function convert_very_strict_label($label)
68 return preg_replace('/[^A-Za-z0-9]/', '_', $label);
72 function check_integer($value)
74 return (empty(preg_match('/[^0-9]/', $value)));
77 //Basename functionality for nonenglish languages (without this, basename function omits nonenglish characters).
78 function basename_international($path)
80 $parts = preg_split('~[\\\\/]~', $path);
81 foreach ($parts as $key => $value) {
82 $encoded = urlencode($value);
83 $parts[$key] = $encoded;
86 $encoded_path = implode("/", $parts);
87 $encoded_file_name = basename($encoded_path);
88 $decoded_file_name = urldecode($encoded_file_name);
90 return $decoded_file_name;
95 * This function detects a MIME type for a file and check if it in the white list of the allowed mime types.
96 * @param string $file - file location.
97 * @param array|null $whiteList - array of mime types that allowed to upload.
99 // Regarding the variable below. In the case of multiple file upload the isWhiteList function will run multiple
100 // times, therefore, storing the white list in the variable below to prevent multiple requests from database.
102 function isWhiteFile($file)
105 if (is_null($white_list)) {
106 $white_list = array();
107 $lres = sqlStatement("SELECT option_id FROM list_options WHERE list_id = 'files_white_list' AND activity = 1");
108 while ($lrow = sqlFetchArray($lres)) {
109 $white_list[] = $lrow['option_id'];
111 // allow module writers to modify the white list... this only gets executed the first time this function runs
112 $event = new IsAcceptedFileFilterEvent($file, $white_list);
113 $resultEvent = $GLOBALS['kernel']->getEventDispatcher()->dispatch(IsAcceptedFileFilterEvent
::EVENT_GET_ACCEPTED_LIST
, $event);
114 $white_list = $resultEvent->getAcceptedList();
117 $mimetype = mime_content_type($file);
118 $isAllowedFile = false;
119 if (in_array($mimetype, $white_list)) {
120 $isAllowedFile = true;
122 $splitMimeType = explode('/', $mimetype);
123 $categoryType = $splitMimeType[0];
124 if (in_array($categoryType . '/*', $white_list)) {
125 $isAllowedFile = true;
126 } else if (isset($GLOBALS['kernel'])) {
127 // we can fire off an event
128 // allow module writers to modify the isWhiteFile on the fly.
129 $event = new IsAcceptedFileFilterEvent($file, $white_list);
130 $event->setAllowedFile(false);
131 $event->setMimeType($mimetype);
132 $resultEvent = $GLOBALS['kernel']->getEventDispatcher()->dispatch(IsAcceptedFileFilterEvent
::EVENT_FILTER_IS_ACCEPTED_FILE
, $event);
133 $isAllowedFile = $resultEvent->isAllowedFile();
137 return $isAllowedFile;
140 // Sanitize a value to ensure it is a number.
141 function sanitizeNumber($number)
143 $clean_number = $number +
0 ;
145 if ($clean_number == $number) {
146 return $clean_number;
148 error_log('Custom validation error: Parameter contains non-numeric value (A numeric value expected)');
149 return $clean_number;
154 * Function to get sql statement for empty datetime check.
156 * @param string $sqlColumn SQL column/field name
157 * @param boolean $time flag used to determine if it's a datetime or a date
158 * @param boolean $rev flag used to reverse the condition
159 * @return string SQL statement checking if passed column is empty
162 function dateEmptySql($sqlColumn, $time = false, $rev = false)
166 $stat = " (`" . $sqlColumn . "` IS NULL OR `" . $sqlColumn . "`= '0000-00-00 00:00:00') ";
168 $stat = " (`" . $sqlColumn . "` IS NULL OR `" . $sqlColumn . "`= '0000-00-00') ";
172 $stat = " (`" . $sqlColumn . "` IS NOT NULL AND `" . $sqlColumn . "`!= '0000-00-00 00:00:00') ";
174 $stat = " (`" . $sqlColumn . "` IS NOT NULL AND `" . $sqlColumn . "`!= '0000-00-00') ";