summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Harvey <aharvey@php.net>2013-11-10 16:11:28 -0500
committerAdam Harvey <aharvey@php.net>2013-11-10 16:11:28 -0500
commit304bff90f42479d412e4124c11803f384cae909d (patch)
tree1c0abe0aa67e1807f84903f893819f1084f64873
parentdf7321359e0c11a1de99285dee64c8e69ee28653 (diff)
parentc9cfd98bcdcd92aa0efebda6ab8a3db5605a6796 (diff)
downloadphp-git-304bff90f42479d412e4124c11803f384cae909d.tar.gz
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4: Update NEWS and remove the unnecessary UPGRADING note. UPGRADING and NEWS Better test: Check combined leading/trailing Fixed whitespace part of bug #64874 ("json_decode handles whitespace and case-sensitivity incorrectly")
-rw-r--r--NEWS7
-rw-r--r--ext/json/json.c30
-rw-r--r--ext/json/tests/bug64874_part1.phpt117
3 files changed, 146 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index d0359fe185..9cacb5fd1a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+?? ??? 2013, PHP 5.5.7
+
+- JSON
+ . Fixed whitespace part of bug #64874 ("json_decode handles whitespace and
+ case-sensitivity incorrectly"). (Andrea Faulds)
+
+
?? ??? 2013, PHP 5.5.6
- Core:
diff --git a/ext/json/json.c b/ext/json/json.c
index 782375e371..c3664b9ee9 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -695,21 +695,35 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len,
double d;
int type, overflow_info;
long p;
+ char *trim = str;
+ int trim_len = str_len;
+
+ /* Increment trimmed string pointer to strip leading whitespace */
+ /* JSON RFC says to consider as whitespace: space, tab, LF or CR */
+ while (trim_len && (*trim == ' ' || *trim == '\t' || *trim == '\n' || *trim == '\r')) {
+ trim++;
+ trim_len--;
+ }
+
+ /* Decrement trimmed string length to strip trailing whitespace */
+ while (trim_len && (trim[trim_len - 1] == ' ' || trim[trim_len - 1] == '\t' || trim[trim_len - 1] == '\n' || trim[trim_len - 1] == '\r')) {
+ trim_len--;
+ }
RETVAL_NULL();
- if (str_len == 4) {
- if (!strcasecmp(str, "null")) {
+ if (trim_len == 4) {
+ if (!strncasecmp(trim, "null", trim_len)) {
/* We need to explicitly clear the error because its an actual NULL and not an error */
jp->error_code = PHP_JSON_ERROR_NONE;
RETVAL_NULL();
- } else if (!strcasecmp(str, "true")) {
+ } else if (!strncasecmp(trim, "true", trim_len)) {
RETVAL_BOOL(1);
}
- } else if (str_len == 5 && !strcasecmp(str, "false")) {
+ } else if (trim_len == 5 && !strncasecmp(trim, "false", trim_len)) {
RETVAL_BOOL(0);
}
- if ((type = is_numeric_string_ex(str, str_len, &p, &d, 0, &overflow_info)) != 0) {
+ if ((type = is_numeric_string_ex(trim, trim_len, &p, &d, 0, &overflow_info)) != 0) {
if (type == IS_LONG) {
RETVAL_LONG(p);
} else if (type == IS_DOUBLE) {
@@ -722,10 +736,10 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len,
int i;
zend_bool is_float = 0;
- for (i = (str[0] == '-' ? 1 : 0); i < str_len; i++) {
+ for (i = (trim[0] == '-' ? 1 : 0); i < trim_len; i++) {
/* Not using isdigit() because it's locale specific,
* but we expect JSON input to always be UTF-8. */
- if (str[i] < '0' || str[i] > '9') {
+ if (trim[i] < '0' || trim[i] > '9') {
is_float = 1;
break;
}
@@ -734,7 +748,7 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len,
if (is_float) {
RETVAL_DOUBLE(d);
} else {
- RETVAL_STRINGL(str, str_len, 1);
+ RETVAL_STRINGL(trim, trim_len, 1);
}
} else {
RETVAL_DOUBLE(d);
diff --git a/ext/json/tests/bug64874_part1.phpt b/ext/json/tests/bug64874_part1.phpt
new file mode 100644
index 0000000000..6b79b8dc04
--- /dev/null
+++ b/ext/json/tests/bug64874_part1.phpt
@@ -0,0 +1,117 @@
+--TEST--
+Whitespace part of bug #64874 ("json_decode handles whitespace and case-sensitivity incorrectly")
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+function decode($json) {
+ var_dump(json_decode($json));
+ var_dump(json_last_error() !== 0);
+ echo "\n";
+}
+
+// Leading whitespace should be ignored
+decode(" true");
+decode("\ttrue");
+decode("\ntrue");
+decode("\rtrue");
+
+// So should trailing whitespace
+decode("true ");
+decode("true\t");
+decode("true\n");
+decode("true\r");
+
+// And so should the combination of both
+decode(" true ");
+decode(" true\t");
+decode(" true\n");
+decode(" true\r");
+decode("\ttrue ");
+decode("\ttrue\t");
+decode("\ttrue\n");
+decode("\ttrue\r");
+decode("\ntrue ");
+decode("\ntrue\t");
+decode("\ntrue\n");
+decode("\ntrue\r");
+decode("\rtrue ");
+decode("\rtrue\t");
+decode("\rtrue\n");
+decode("\rtrue\r");
+
+echo "Done\n";
+--EXPECT--
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+
+Done