summaryrefslogtreecommitdiff
path: root/ext/json
diff options
context:
space:
mode:
Diffstat (limited to 'ext/json')
-rw-r--r--ext/json/JSON_parser.c12
-rw-r--r--ext/json/json.c31
-rw-r--r--ext/json/php_json.h4
-rw-r--r--ext/json/tests/001.phpt32
-rw-r--r--ext/json/tests/bug41567.phpt4
-rw-r--r--ext/json/tests/bug42090.phpt9
-rw-r--r--ext/json/tests/bug43941.phpt21
-rw-r--r--ext/json/tests/bug46215.phpt29
-rw-r--r--ext/json/tests/bug46944.phpt35
-rw-r--r--ext/json/tests/fail001.phpt4
-rw-r--r--ext/json/utf8_decode.c2
-rw-r--r--ext/json/utf8_to_utf16.c4
12 files changed, 135 insertions, 52 deletions
diff --git a/ext/json/JSON_parser.c b/ext/json/JSON_parser.c
index c054d5038..a88dde9fa 100644
--- a/ext/json/JSON_parser.c
+++ b/ext/json/JSON_parser.c
@@ -201,7 +201,7 @@ static const int state_transition_table[30][31] = {
/*29*/ {29,29,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
};
-#define JSON_PARSER_MAX_DEPTH 128
+#define JSON_PARSER_MAX_DEPTH 512
/*
@@ -285,7 +285,7 @@ static void json_create_zval(zval **z, smart_str *buf, int type)
if (type == IS_LONG)
{
double d = zend_strtod(buf->c, NULL);
- if (d > LONG_MAX || d < -LONG_MAX) {
+ if (d > LONG_MAX || d < LONG_MIN) {
ZVAL_DOUBLE(*z, d);
} else {
ZVAL_LONG(*z, (long)d);
@@ -494,9 +494,7 @@ JSON_parser(zval *z, unsigned short p[], int length, int assoc TSRMLS_DC)
}
*/
case -7:
- if (type != -1 &&
- (JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
- JSON(the_stack)[JSON(the_top)] == MODE_ARRAY))
+ if (type != -1 && JSON(the_stack)[JSON(the_top)] == MODE_OBJECT)
{
zval *mval;
smart_str_0(&buf);
@@ -566,9 +564,7 @@ JSON_parser(zval *z, unsigned short p[], int length, int assoc TSRMLS_DC)
*/
case -5:
{
- if (type != -1 &&
- (JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
- JSON(the_stack)[JSON(the_top)] == MODE_ARRAY))
+ if (type != -1 && JSON(the_stack)[JSON(the_top)] == MODE_ARRAY)
{
zval *mval;
smart_str_0(&buf);
diff --git a/ext/json/json.c b/ext/json/json.c
index e7bb805e7..826d36751 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2008 The PHP Group |
+ | Copyright (c) 1997-2009 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: json.c,v 1.9.2.21 2007/12/31 07:20:07 sebastian Exp $ */
+/* $Id: json.c,v 1.9.2.26 2009/02/12 00:36:23 scottmac Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -84,7 +84,7 @@ static PHP_MINFO_FUNCTION(json)
/* }}} */
static void json_encode_r(smart_str *buf, zval *val TSRMLS_DC);
-static void json_escape_string(smart_str *buf, char *s, int len);
+static void json_escape_string(smart_str *buf, char *s, int len TSRMLS_DC);
static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */
{
@@ -181,6 +181,9 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) { /* {{{ */
if (i == HASH_KEY_IS_STRING) {
if (key[0] == '\0' && Z_TYPE_PP(val) == IS_OBJECT) {
/* Skip protected and private members. */
+ if (tmp_ht) {
+ tmp_ht->nApplyCount--;
+ }
continue;
}
@@ -190,7 +193,7 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) { /* {{{ */
need_comma = 1;
}
- json_escape_string(buf, key, key_len - 1);
+ json_escape_string(buf, key, key_len - 1 TSRMLS_CC);
smart_str_appendc(buf, ':');
json_encode_r(buf, *data TSRMLS_CC);
@@ -230,7 +233,7 @@ static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) { /* {{{ */
#define REVERSE16(us) (((us & 0xf) << 12) | (((us >> 4) & 0xf) << 8) | (((us >> 8) & 0xf) << 4) | ((us >> 12) & 0xf))
-static void json_escape_string(smart_str *buf, char *s, int len) /* {{{ */
+static void json_escape_string(smart_str *buf, char *s, int len TSRMLS_DC) /* {{{ */
{
int pos = 0;
unsigned short us;
@@ -251,8 +254,14 @@ static void json_escape_string(smart_str *buf, char *s, int len) /* {{{ */
{
efree(utf16);
}
-
- smart_str_appendl(buf, "\"\"", 2);
+ if(len < 0) {
+ if(!PG(display_errors)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument");
+ }
+ smart_str_appendl(buf, "null", 4);
+ } else {
+ smart_str_appendl(buf, "\"\"", 2);
+ }
return;
}
@@ -369,7 +378,7 @@ static void json_encode_r(smart_str *buf, zval *val TSRMLS_DC) /* {{{ */
}
break;
case IS_STRING:
- json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val));
+ json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val) TSRMLS_CC);
break;
case IS_ARRAY:
case IS_OBJECT:
@@ -470,13 +479,7 @@ static PHP_FUNCTION(json_decode)
RETURN_DOUBLE(d);
}
}
- if (parameter_len > 1 && *parameter == '"' && parameter[parameter_len-1] == '"') {
- RETURN_STRINGL(parameter+1, parameter_len-2, 1);
- } else if (*parameter == '{' || *parameter == '[') { /* invalid JSON string */
RETURN_NULL();
- } else {
- RETURN_STRINGL(parameter, parameter_len, 1);
- }
}
}
/* }}} */
diff --git a/ext/json/php_json.h b/ext/json/php_json.h
index 27ef7a0ac..13aab3c62 100644
--- a/ext/json/php_json.h
+++ b/ext/json/php_json.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2008 The PHP Group |
+ | Copyright (c) 1997-2009 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_json.h,v 1.8.2.3 2007/12/31 07:20:07 sebastian Exp $ */
+/* $Id: php_json.h,v 1.8.2.4 2008/12/31 11:17:38 sebastian Exp $ */
#ifndef PHP_JSON_H
#define PHP_JSON_H
diff --git a/ext/json/tests/001.phpt b/ext/json/tests/001.phpt
index 4c9f918b4..02d43c424 100644
--- a/ext/json/tests/001.phpt
+++ b/ext/json/tests/001.phpt
@@ -23,49 +23,49 @@ var_dump(json_decode('{ "": { "": "" } }'));
var_dump(json_decode('{ "": { "": "" }'));
var_dump(json_decode('{ "": "": "" } }'));
-echo "Done\n";
?>
+===DONE===
--EXPECTF--
Warning: json_decode() expects at least 1 parameter, 0 given in %s on line %d
NULL
NULL
NULL
NULL
-string(1) "."
-string(1) "."
-string(3) "<?>"
-string(1) ";"
-string(12) "руссиш"
-string(4) "blah"
NULL
-object(stdClass)#1 (1) {
+NULL
+NULL
+NULL
+NULL
+NULL
+NULL
+object(stdClass)#%d (1) {
["test"]=>
- object(stdClass)#2 (1) {
+ object(stdClass)#%d (1) {
["foo"]=>
string(3) "bar"
}
}
-object(stdClass)#1 (1) {
+object(stdClass)#%d (1) {
["test"]=>
- object(stdClass)#2 (1) {
+ object(stdClass)#%d (1) {
["foo"]=>
string(0) ""
}
}
-object(stdClass)#1 (1) {
+object(stdClass)#%d (1) {
["_empty_"]=>
- object(stdClass)#2 (1) {
+ object(stdClass)#%d (1) {
["foo"]=>
string(0) ""
}
}
-object(stdClass)#1 (1) {
+object(stdClass)#%d (1) {
["_empty_"]=>
- object(stdClass)#2 (1) {
+ object(stdClass)#%d (1) {
["_empty_"]=>
string(0) ""
}
}
NULL
NULL
-Done
+===DONE===
diff --git a/ext/json/tests/bug41567.phpt b/ext/json/tests/bug41567.phpt
index 5a141003e..a253a47b7 100644
--- a/ext/json/tests/bug41567.phpt
+++ b/ext/json/tests/bug41567.phpt
@@ -1,5 +1,7 @@
--TEST--
Bug #41567 (json_encode() double conversion is inconsistent with PHP)
+--INI--
+precision=14
--SKIPIF--
<?php if (!extension_loaded('json')) print 'skip'; ?>
--FILE--
@@ -10,8 +12,6 @@ var_dump(json_decode($a));
echo "Done\n";
?>
---INI--
-precision=14
--EXPECT--
float(123456789.12345)
Done
diff --git a/ext/json/tests/bug42090.phpt b/ext/json/tests/bug42090.phpt
index bccd28aba..9e5b3317e 100644
--- a/ext/json/tests/bug42090.phpt
+++ b/ext/json/tests/bug42090.phpt
@@ -1,5 +1,5 @@
--TEST--
-Bug#42090 (json_decode causes segmentation fault)
+Bug #42090 (json_decode causes segmentation fault)
--SKIPIF--
<?php if (!extension_loaded("json")) print "skip"; ?>
--FILE--
@@ -16,10 +16,9 @@ var_dump(
?>
--EXPECT--
string(0) ""
-string(5) "".."."
-string(1) """
-string(2) """"
+NULL
+NULL
+NULL
string(4) ""\"""
string(1) """
string(2) """"
-
diff --git a/ext/json/tests/bug43941.phpt b/ext/json/tests/bug43941.phpt
new file mode 100644
index 000000000..0f86d1dfa
--- /dev/null
+++ b/ext/json/tests/bug43941.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #43941 (json_encode() invalid UTF-8)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+var_dump(json_encode("abc"));
+var_dump(json_encode("ab\xE0"));
+var_dump(json_encode("ab\xE0c"));
+var_dump(json_encode(array("ab\xE0", "ab\xE0c", "abc")));
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(5) ""abc""
+string(4) "null"
+string(4) "null"
+string(17) "[null,null,"abc"]"
+Done
+
diff --git a/ext/json/tests/bug46215.phpt b/ext/json/tests/bug46215.phpt
new file mode 100644
index 000000000..0ac460cc1
--- /dev/null
+++ b/ext/json/tests/bug46215.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #46215 (json_encode mutates its parameter and has some class-specific state)
+--SKIPIF--
+<?php
+if (!extension_loaded("json")) {
+ die('skip JSON extension not available in this build');
+}
+?>
+--FILE--
+<?php
+
+class foo {
+ protected $a = array();
+}
+
+$a = new foo;
+$x = json_encode($a);
+
+print_r($a);
+
+?>
+--EXPECT--
+foo Object
+(
+ [a:protected] => Array
+ (
+ )
+
+)
diff --git a/ext/json/tests/bug46944.phpt b/ext/json/tests/bug46944.phpt
new file mode 100644
index 000000000..812a54887
--- /dev/null
+++ b/ext/json/tests/bug46944.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #46944 (json_encode() doesn't handle 3 byte utf8 correctly)
+--SKIPIF--
+<?php if (!extension_loaded('json')) print 'skip'; ?>
+--FILE--
+<?php
+
+for ($i = 1; $i <= 16; $i++) {
+ $first = 0xf0|($i >> 2);
+ $second = 0x8f|($i & 3) << 4;
+ $string = sprintf("aa%c%c\xbf\xbdzz", $first, $second);
+ echo json_encode($string) . "\n";
+}
+
+
+echo "Done\n";
+?>
+--EXPECT--
+"aa\ud83f\udffdzz"
+"aa\ud87f\udffdzz"
+"aa\ud8bf\udffdzz"
+"aa\ud8ff\udffdzz"
+"aa\ud93f\udffdzz"
+"aa\ud97f\udffdzz"
+"aa\ud9bf\udffdzz"
+"aa\ud9ff\udffdzz"
+"aa\uda3f\udffdzz"
+"aa\uda7f\udffdzz"
+"aa\udabf\udffdzz"
+"aa\udaff\udffdzz"
+"aa\udb3f\udffdzz"
+"aa\udb7f\udffdzz"
+"aa\udbbf\udffdzz"
+"aa\udbff\udffdzz"
+Done
diff --git a/ext/json/tests/fail001.phpt b/ext/json/tests/fail001.phpt
index 525bc048c..1bf9f1210 100644
--- a/ext/json/tests/fail001.phpt
+++ b/ext/json/tests/fail001.phpt
@@ -24,7 +24,7 @@ $tests = array('"A JSON payload should be an object or array, not a string."',
'["Illegal backslash escape: \\x15"]',
'["Illegal backslash escape: \\\'"]',
'["Illegal backslash escape: \\017"]',
- '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]',
+ '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]',
'{"Missing colon" null}',
'{"Double colon":: null}',
'{"Comma instead of colon", null}',
@@ -128,7 +128,7 @@ AS OBJECT
NULL
AS ARRAY
NULL
-Testing: [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
+Testing: [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
AS OBJECT
NULL
AS ARRAY
diff --git a/ext/json/utf8_decode.c b/ext/json/utf8_decode.c
index cea1f8cec..2d0422bed 100644
--- a/ext/json/utf8_decode.c
+++ b/ext/json/utf8_decode.c
@@ -165,7 +165,7 @@ utf8_decode_next(json_utf8_decode *utf8)
/*
Three continuation (65536 to 1114111)
*/
- if ((c & 0xF1) == 0xF0) {
+ if ((c & 0xF8) == 0xF0) {
int c1 = cont(utf8);
int c2 = cont(utf8);
int c3 = cont(utf8);
diff --git a/ext/json/utf8_to_utf16.c b/ext/json/utf8_to_utf16.c
index bc2d6f36d..599f0e13b 100644
--- a/ext/json/utf8_to_utf16.c
+++ b/ext/json/utf8_to_utf16.c
@@ -40,13 +40,13 @@ utf8_to_utf16(unsigned short w[], char p[], int length)
for (;;) {
c = utf8_decode_next(&utf8);
if (c < 0) {
- return UTF8_END ? the_index : UTF8_ERROR;
+ return (c == UTF8_END) ? the_index : UTF8_ERROR;
}
if (c < 0x10000) {
w[the_index] = (unsigned short)c;
the_index += 1;
} else {
- c &= 0xFFFF;
+ c -= 0x10000;
w[the_index] = (unsigned short)(0xD800 | (c >> 10));
the_index += 1;
w[the_index] = (unsigned short)(0xDC00 | (c & 0x3FF));