diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php
index 4e32cb552da..6ba9946dd90 100644
--- a/htdocs/admin/system/security.php
+++ b/htdocs/admin/system/security.php
@@ -190,10 +190,10 @@ print '
';
print 'JSON: ';
$loadedExtensions = array_map('strtolower', get_loaded_extensions(false));
$test = !in_array('json', $loadedExtensions);
-if ($test) {
+if ($test || function_exists('dol_json_decode')) {
print img_picto('', 'error').' '.$langs->trans("NotInstalled").' - '.$langs->trans("VulnerableToRCEAttack");
} else {
- print img_picto('', 'tick').' '.$langs->trans("Available");
+ print img_picto('', 'tick').' '.$langs->trans("Available").' (PHP native so not emulated, safe)';
}
print '
';
diff --git a/htdocs/core/lib/json.lib.php b/htdocs/core/lib/json.lib.php
index d9c3d09008a..6d527a881e8 100644
--- a/htdocs/core/lib/json.lib.php
+++ b/htdocs/core/lib/json.lib.php
@@ -25,6 +25,235 @@
* \ingroup core
*/
+if (!function_exists('json_encode') || defined('PHPUNIT_MODE')) {
+ /**
+ * Implement json_encode for PHP that does not support it.
+ * Use json_encode and json_decode in your code !
+ * Note: We can found some special chars into a json string:
+ * Quotation mark (") = \", Backslash (\) = \\, Slash (/) = \/, Backspace = \b, Form feed = \f, New line =\n, Carriage return =\r, Horizontal tab = \t
+ *
+ * @param mixed $elements PHP Object to json encode
+ * @return string Json encoded string
+ * @see json_encode()
+ */
+ function dol_json_encode($elements)
+ {
+ dol_syslog("For better performance, enable the native json in your PHP", LOG_WARNING);
+
+ $num = 0;
+ if (is_object($elements)) { // Count number of properties for an object
+ foreach ($elements as $key => $value) {
+ $num++;
+ }
+ } else {
+ if (is_countable($elements)) {
+ $num = count($elements);
+ }
+ }
+
+ // determine type
+ if (is_numeric($elements)) {
+ return $elements;
+ } elseif (is_string($elements)) {
+ return '"'.$elements.'"';
+ }
+ if (is_numeric(key($elements)) && key($elements) == 0) {
+ // indexed (list)
+ $keysofelements = array_keys($elements); // Elements array must have key that does not start with 0 and end with num-1, so we will use this later.
+ $output = '[';
+ for ($i = 0, $last = ($num - 1); $i < $num; $i++) {
+ if (!isset($elements[$keysofelements[$i]])) {
+ continue;
+ }
+ if (is_array($elements[$keysofelements[$i]]) || is_object($elements[$keysofelements[$i]])) {
+ $output .= json_encode($elements[$keysofelements[$i]]);
+ } else {
+ $output .= _val($elements[$keysofelements[$i]]);
+ }
+ if ($i !== $last) {
+ $output .= ',';
+ }
+ }
+ $output .= ']';
+ } else {
+ // associative (object)
+ $output = '{';
+ $last = $num - 1;
+ $i = 0;
+ $tmpelements = array();
+ if (is_array($elements)) {
+ $tmpelements = $elements;
+ }
+ if (is_object($elements)) {
+ $tmpelements = get_object_vars($elements);
+ }
+ foreach ($tmpelements as $key => $value) {
+ $output .= '"'.$key.'":';
+ if (is_array($value)) {
+ $output .= json_encode($value);
+ } else {
+ $output .= _val($value);
+ }
+ if ($i !== $last) {
+ $output .= ',';
+ }
+ ++$i;
+ }
+ $output .= '}';
+ }
+
+ // return
+ return $output;
+ }
+
+ /**
+ * Return text according to type
+ *
+ * @param mixed $val Value to show
+ * @return string Formatted value
+ */
+ function _val($val)
+ {
+ if (is_string($val)) {
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+ $ascii = '';
+ $strlen_var = strlen($val);
+
+ /*
+ * Iterate over every character in the string,
+ * escaping with a slash or encoding to UTF-8 where necessary
+ */
+ for ($c = 0; $c < $strlen_var; ++$c) {
+ $ord_var_c = ord($val[$c]);
+
+ switch (true) {
+ case $ord_var_c == 0x08:
+ $ascii .= '\b';
+ break;
+ case $ord_var_c == 0x09:
+ $ascii .= '\t';
+ break;
+ case $ord_var_c == 0x0A:
+ $ascii .= '\n';
+ break;
+ case $ord_var_c == 0x0C:
+ $ascii .= '\f';
+ break;
+ case $ord_var_c == 0x0D:
+ $ascii .= '\r';
+ break;
+
+ case $ord_var_c == 0x22:
+ case $ord_var_c == 0x2F:
+ case $ord_var_c == 0x5C:
+ // double quote, slash, slosh
+ $ascii .= '\\'.$val[$c];
+ break;
+
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+ // characters U-00000000 - U-0000007F (same as ASCII)
+ $ascii .= $val[$c];
+ break;
+
+ case (($ord_var_c & 0xE0) == 0xC0):
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($val[$c + 1]));
+ $c += 1;
+ $utf16 = utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF0) == 0xE0):
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]));
+ $c += 2;
+ $utf16 = utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF8) == 0xF0):
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]), ord($val[$c + 3]));
+ $c += 3;
+ $utf16 = utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFC) == 0xF8):
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]), ord($val[$c + 3]), ord($val[$c + 4]));
+ $c += 4;
+ $utf16 = utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFE) == 0xFC):
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]), ord($val[$c + 3]), ord($val[$c + 4]), ord($val[$c + 5]));
+ $c += 5;
+ $utf16 = utf82utf16($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+ }
+ }
+
+ return '"'.$ascii.'"';
+ } elseif (is_int($val)) {
+ return sprintf('%d', $val);
+ } elseif (is_float($val)) {
+ return sprintf('%F', $val);
+ } elseif (is_bool($val)) {
+ return ($val ? 'true' : 'false');
+ } else {
+ return 'null';
+ }
+ }
+
+
+ /**
+ * Convert a string from one UTF-8 char to one UTF-16 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibyte string extension.
+ *
+ * @param string $utf8 UTF-8 character
+ * @return string UTF-16 character
+ */
+ function utf82utf16($utf8)
+ {
+ // oh please oh please oh please oh please oh please
+ if (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
+ }
+
+ switch (strlen($utf8)) {
+ case 1:
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return $utf8;
+
+ case 2:
+ // return a UTF-16 character from a 2-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0x07 & (ord($utf8[0]) >> 2)).chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1])));
+
+ case 3:
+ // return a UTF-16 character from a 3-byte UTF-8 char
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr((0xF0 & (ord($utf8[0]) << 4)) | (0x0F & (ord($utf8[1]) >> 2))).chr((0xC0 & (ord($utf8[1]) << 6)) | (0x7F & ord($utf8[2])));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
+ }
+}
+
if (!function_exists('json_encode')) {
/**
* Implement json_encode for PHP that does not have module enabled.
@@ -40,191 +269,148 @@ if (!function_exists('json_encode')) {
}
-/**
- * Implement json_encode for PHP that does not support it.
- * Use json_encode and json_decode in your code !
- * Note: We can found some special chars into a json string:
- * Quotation mark (") = \", Backslash (\) = \\, Slash (/) = \/, Backspace = \b, Form feed = \f, New line =\n, Carriage return =\r, Horizontal tab = \t
- *
- * @param mixed $elements PHP Object to json encode
- * @return string Json encoded string
- * @see json_encode()
- */
-function dol_json_encode($elements)
-{
- dol_syslog("For better performance, enable the native json in your PHP", LOG_WARNING);
+if (!function_exists('json_decode') || defined('PHPUNIT_MODE')) {
+ /**
+ * Implement json_decode for PHP that does not support it
+ * Use json_encode and json_decode in your code !
+ *
+ * @param string $json Json encoded to PHP Object or Array
+ * @param bool $assoc False return an object, true return an array. Try to always use it with true !
+ * @return mixed Object or Array or false on error
+ * @see json_decode()
+ */
+ function dol_json_decode($json, $assoc = false)
+ {
+ dol_syslog("For better performance and security, enable the native json in your PHP", LOG_WARNING);
- $num = 0;
- if (is_object($elements)) { // Count number of properties for an object
- foreach ($elements as $key => $value) {
- $num++;
- }
- } else {
- if (is_countable($elements)) {
- $num = count($elements);
- }
- }
+ $comment = false;
- // determine type
- if (is_numeric($elements)) {
- return $elements;
- } elseif (is_string($elements)) {
- return '"'.$elements.'"';
- }
- if (is_numeric(key($elements)) && key($elements) == 0) {
- // indexed (list)
- $keysofelements = array_keys($elements); // Elements array must have key that does not start with 0 and end with num-1, so we will use this later.
- $output = '[';
- for ($i = 0, $last = ($num - 1); $i < $num; $i++) {
- if (!isset($elements[$keysofelements[$i]])) {
- continue;
- }
- if (is_array($elements[$keysofelements[$i]]) || is_object($elements[$keysofelements[$i]])) {
- $output .= json_encode($elements[$keysofelements[$i]]);
+ $out = '';
+ $strLength = strlen($json); // Must stay strlen and not dol_strlen because we want technical length, not visible length
+
+ if (is_numeric($json)) {
+ return $json;
+ }
+
+ for ($i = 0; $i < $strLength; $i++) {
+ if (!$comment) {
+ if ($i == 0 && !in_array($json[$i], array('{', '[', '"', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))) {
+ // Not a json format
+ return false;
+ }
+ if (($json[$i] == '{') || ($json[$i] == '[')) {
+ $out .= 'array(';
+ } elseif (($json[$i] == '}') || ($json[$i] == ']')) {
+ $out .= ')';
+ } elseif ($json[$i] == ':') {
+ $out .= ' => ';
+ } else {
+ $out .= $json[$i];
+ }
} else {
- $output .= _val($elements[$keysofelements[$i]]);
+ $out .= $json[$i];
}
- if ($i !== $last) {
- $output .= ',';
+ // @phan-suppress-next-line PhanCompatibleNegativeStringOffset
+ if ($i >= 1 && $json[$i] == '"' && $json[$i - 1] != "\\") {
+ $comment = !$comment;
}
}
- $output .= ']';
- } else {
- // associative (object)
- $output = '{';
- $last = $num - 1;
- $i = 0;
- $tmpelements = array();
- if (is_array($elements)) {
- $tmpelements = $elements;
- }
- if (is_object($elements)) {
- $tmpelements = get_object_vars($elements);
- }
- foreach ($tmpelements as $key => $value) {
- $output .= '"'.$key.'":';
- if (is_array($value)) {
- $output .= json_encode($value);
- } else {
- $output .= _val($value);
+
+ $out = _unval($out);
+
+ $array = array();
+
+ // Return an array
+ if ($out != '') {
+ try {
+ // @phan-suppress-next-line PhanPluginUnsafeEval
+ eval('$array = '.$out.';'); // not secured but this is no mode used as php json lib is always expected to be loaded now.
+ } catch (Exception $e) {
+ $array = array();
}
- if ($i !== $last) {
- $output .= ',';
- }
- ++$i;
}
- $output .= '}';
+
+ // Return an object
+ if (!$assoc) {
+ if (!empty($array)) {
+ $object = false;
+ if (count($array) > 0) {
+ $object = (object) array();
+ }
+ foreach ($array as $key => $value) {
+ if ($key) {
+ $object->{$key} = $value;
+ }
+ }
+
+ return $object;
+ }
+
+ return false;
+ }
+
+ return $array;
}
- // return
- return $output;
-}
+ /**
+ * Return text according to type
+ *
+ * @param string $val Value to decode
+ * @return string Formatted value
+ */
+ function _unval($val)
+ {
+ $reg = array();
+ while (preg_match('/\\\u([0-9A-F]{2})([0-9A-F]{2})/i', $val, $reg)) {
+ // single, escaped unicode character
+ $utf16 = chr(hexdec($reg[1])).chr(hexdec($reg[2]));
+ $utf8 = utf162utf8($utf16);
+ $val = preg_replace('/\\\u'.$reg[1].$reg[2].'/i', $utf8, $val);
+ }
+ return $val;
+ }
-/**
- * Return text according to type
- *
- * @param mixed $val Value to show
- * @return string Formatted value
- */
-function _val($val)
-{
- if (is_string($val)) {
- // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
- $ascii = '';
- $strlen_var = strlen($val);
-
- /*
- * Iterate over every character in the string,
- * escaping with a slash or encoding to UTF-8 where necessary
- */
- for ($c = 0; $c < $strlen_var; ++$c) {
- $ord_var_c = ord($val[$c]);
-
- switch (true) {
- case $ord_var_c == 0x08:
- $ascii .= '\b';
- break;
- case $ord_var_c == 0x09:
- $ascii .= '\t';
- break;
- case $ord_var_c == 0x0A:
- $ascii .= '\n';
- break;
- case $ord_var_c == 0x0C:
- $ascii .= '\f';
- break;
- case $ord_var_c == 0x0D:
- $ascii .= '\r';
- break;
-
- case $ord_var_c == 0x22:
- case $ord_var_c == 0x2F:
- case $ord_var_c == 0x5C:
- // double quote, slash, slosh
- $ascii .= '\\'.$val[$c];
- break;
-
- case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
- // characters U-00000000 - U-0000007F (same as ASCII)
- $ascii .= $val[$c];
- break;
-
- case (($ord_var_c & 0xE0) == 0xC0):
- // characters U-00000080 - U-000007FF, mask 110XXXXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c, ord($val[$c + 1]));
- $c += 1;
- $utf16 = utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
-
- case (($ord_var_c & 0xF0) == 0xE0):
- // characters U-00000800 - U-0000FFFF, mask 1110XXXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]));
- $c += 2;
- $utf16 = utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
-
- case (($ord_var_c & 0xF8) == 0xF0):
- // characters U-00010000 - U-001FFFFF, mask 11110XXX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]), ord($val[$c + 3]));
- $c += 3;
- $utf16 = utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
-
- case (($ord_var_c & 0xFC) == 0xF8):
- // characters U-00200000 - U-03FFFFFF, mask 111110XX
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]), ord($val[$c + 3]), ord($val[$c + 4]));
- $c += 4;
- $utf16 = utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
-
- case (($ord_var_c & 0xFE) == 0xFC):
- // characters U-04000000 - U-7FFFFFFF, mask 1111110X
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- $char = pack('C*', $ord_var_c, ord($val[$c + 1]), ord($val[$c + 2]), ord($val[$c + 3]), ord($val[$c + 4]), ord($val[$c + 5]));
- $c += 5;
- $utf16 = utf82utf16($char);
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
- break;
- }
+ /**
+ * Convert a string from one UTF-16 char to one UTF-8 char
+ *
+ * Normally should be handled by mb_convert_encoding, but
+ * provides a slower PHP-only method for installations
+ * that lack the multibyte string extension.
+ *
+ * @param string $utf16 UTF-16 character
+ * @return string UTF-8 character
+ */
+ function utf162utf8($utf16)
+ {
+ // oh please oh please oh please oh please oh please
+ if (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
}
- return '"'.$ascii.'"';
- } elseif (is_int($val)) {
- return sprintf('%d', $val);
- } elseif (is_float($val)) {
- return sprintf('%F', $val);
- } elseif (is_bool($val)) {
- return ($val ? 'true' : 'false');
- } else {
- return 'null';
+ $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);
+
+ switch (true) {
+ case ((0x7F & $bytes) == $bytes):
+ // this case should never be reached, because we are in ASCII range
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr($bytes);
+
+ case (0x07FF & $bytes) == $bytes:
+ // return a 2-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
+ . chr(0x80 | ($bytes & 0x3F));
+
+ case (0xFFFF & $bytes) == $bytes:
+ // return a 3-byte UTF-8 character
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
+ . chr(0x80 | ($bytes & 0x3F));
+ }
+
+ // ignoring UTF-32 for now, sorry
+ return '';
}
}
@@ -241,185 +427,4 @@ if (!function_exists('json_decode')) {
{
return dol_json_decode($json, $assoc);
}
-}
-
-/**
- * Implement json_decode for PHP that does not support it
- * Use json_encode and json_decode in your code !
- *
- * @param string $json Json encoded to PHP Object or Array
- * @param bool $assoc False return an object, true return an array. Try to always use it with true !
- * @return mixed Object or Array or false on error
- * @see json_decode()
- */
-function dol_json_decode($json, $assoc = false)
-{
- dol_syslog("For better performance and security, enable the native json in your PHP", LOG_WARNING);
-
- $comment = false;
-
- $out = '';
- $strLength = strlen($json); // Must stay strlen and not dol_strlen because we want technical length, not visible length
-
- if (is_numeric($json)) {
- return $json;
- }
-
- for ($i = 0; $i < $strLength; $i++) {
- if (!$comment) {
- if ($i == 0 && !in_array($json[$i], array('{', '[', '"', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))) {
- // Not a json format
- return false;
- }
- if (($json[$i] == '{') || ($json[$i] == '[')) {
- $out .= 'array(';
- } elseif (($json[$i] == '}') || ($json[$i] == ']')) {
- $out .= ')';
- } elseif ($json[$i] == ':') {
- $out .= ' => ';
- } else {
- $out .= $json[$i];
- }
- } else {
- $out .= $json[$i];
- }
- // @phan-suppress-next-line PhanCompatibleNegativeStringOffset
- if ($i >= 1 && $json[$i] == '"' && $json[$i - 1] != "\\") {
- $comment = !$comment;
- }
- }
-
- $out = _unval($out);
-
- $array = array();
-
- // Return an array
- if ($out != '') {
- try {
- // @phan-suppress-next-line PhanPluginUnsafeEval
- eval('$array = '.$out.';'); // not secured but this is no mode used as php json lib is always expected to be loaded now.
- } catch (Exception $e) {
- $array = array();
- }
- }
-
- // Return an object
- if (!$assoc) {
- if (!empty($array)) {
- $object = false;
- if (count($array) > 0) {
- $object = (object) array();
- }
- foreach ($array as $key => $value) {
- if ($key) {
- $object->{$key} = $value;
- }
- }
-
- return $object;
- }
-
- return false;
- }
-
- return $array;
-}
-
-/**
- * Return text according to type
- *
- * @param string $val Value to decode
- * @return string Formatted value
- */
-function _unval($val)
-{
- $reg = array();
- while (preg_match('/\\\u([0-9A-F]{2})([0-9A-F]{2})/i', $val, $reg)) {
- // single, escaped unicode character
- $utf16 = chr(hexdec($reg[1])).chr(hexdec($reg[2]));
- $utf8 = utf162utf8($utf16);
- $val = preg_replace('/\\\u'.$reg[1].$reg[2].'/i', $utf8, $val);
- }
- return $val;
-}
-
-/**
- * Convert a string from one UTF-16 char to one UTF-8 char
- *
- * Normally should be handled by mb_convert_encoding, but
- * provides a slower PHP-only method for installations
- * that lack the multibyte string extension.
- *
- * @param string $utf16 UTF-16 character
- * @return string UTF-8 character
- */
-function utf162utf8($utf16)
-{
- // oh please oh please oh please oh please oh please
- if (function_exists('mb_convert_encoding')) {
- return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
- }
-
- $bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);
-
- switch (true) {
- case ((0x7F & $bytes) == $bytes):
- // this case should never be reached, because we are in ASCII range
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr($bytes);
-
- case (0x07FF & $bytes) == $bytes:
- // return a 2-byte UTF-8 character
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0xC0 | (($bytes >> 6) & 0x1F))
- . chr(0x80 | ($bytes & 0x3F));
-
- case (0xFFFF & $bytes) == $bytes:
- // return a 3-byte UTF-8 character
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0xE0 | (($bytes >> 12) & 0x0F))
- . chr(0x80 | (($bytes >> 6) & 0x3F))
- . chr(0x80 | ($bytes & 0x3F));
- }
-
- // ignoring UTF-32 for now, sorry
- return '';
-}
-
-/**
- * Convert a string from one UTF-8 char to one UTF-16 char
- *
- * Normally should be handled by mb_convert_encoding, but
- * provides a slower PHP-only method for installations
- * that lack the multibyte string extension.
- *
- * @param string $utf8 UTF-8 character
- * @return string UTF-16 character
- */
-function utf82utf16($utf8)
-{
- // oh please oh please oh please oh please oh please
- if (function_exists('mb_convert_encoding')) {
- return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
- }
-
- switch (strlen($utf8)) {
- case 1:
- // this case should never be reached, because we are in ASCII range
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return $utf8;
-
- case 2:
- // return a UTF-16 character from a 2-byte UTF-8 char
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr(0x07 & (ord($utf8[0]) >> 2)).chr((0xC0 & (ord($utf8[0]) << 6)) | (0x3F & ord($utf8[1])));
-
- case 3:
- // return a UTF-16 character from a 3-byte UTF-8 char
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
- return chr((0xF0 & (ord($utf8[0]) << 4)) | (0x0F & (ord($utf8[1]) >> 2))).chr((0xC0 & (ord($utf8[1]) << 6)) | (0x7F & ord($utf8[2])));
- }
-
- // ignoring UTF-32 for now, sorry
- return '';
-}
+}
\ No newline at end of file
diff --git a/test/phpunit/JsonLibTest.php b/test/phpunit/JsonLibTest.php
index 113c13a804d..177093e190c 100644
--- a/test/phpunit/JsonLibTest.php
+++ b/test/phpunit/JsonLibTest.php
@@ -24,6 +24,8 @@
* \remarks To run this script as CLI: phpunit filename.php
*/
+define('PHPUNIT_MODE', 1);
+
global $conf,$user,$langs,$db;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';