diff options
Diffstat (limited to 'ext/json')
| -rw-r--r-- | ext/json/JSON_parser.c | 12 | ||||
| -rw-r--r-- | ext/json/json.c | 31 | ||||
| -rw-r--r-- | ext/json/php_json.h | 4 | ||||
| -rw-r--r-- | ext/json/tests/001.phpt | 32 | ||||
| -rw-r--r-- | ext/json/tests/bug41567.phpt | 4 | ||||
| -rw-r--r-- | ext/json/tests/bug42090.phpt | 9 | ||||
| -rw-r--r-- | ext/json/tests/bug43941.phpt | 21 | ||||
| -rw-r--r-- | ext/json/tests/bug46215.phpt | 29 | ||||
| -rw-r--r-- | ext/json/tests/bug46944.phpt | 35 | ||||
| -rw-r--r-- | ext/json/tests/fail001.phpt | 4 | ||||
| -rw-r--r-- | ext/json/utf8_decode.c | 2 | ||||
| -rw-r--r-- | ext/json/utf8_to_utf16.c | 4 |
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)); |
