|
|
@ -98,6 +98,14 @@ int json_yydebug = 1; |
|
|
|
#define PHP_JSON_USE_1(uvr, uv1) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1) |
|
|
|
#define PHP_JSON_USE_2(uvr, uv1, uv2) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1); PHP_JSON_USE(uv2) |
|
|
|
|
|
|
|
#define PHP_JSON_DEPTH_DEC --parser->depth |
|
|
|
#define PHP_JSON_DEPTH_INC \ |
|
|
|
if (parser->max_depth && parser->depth >= parser->max_depth) { \ |
|
|
|
parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \ |
|
|
|
YYERROR; \ |
|
|
|
} \ |
|
|
|
++parser->depth |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -201,20 +209,9 @@ int php_json_yyparse (php_json_parser *parser); |
|
|
|
/* Unqualified %code blocks. */ |
|
|
|
|
|
|
|
|
|
|
|
int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); |
|
|
|
void php_json_yyerror(php_json_parser *parser, char const *msg); |
|
|
|
void php_json_parser_object_init(php_json_parser *parser, zval *object); |
|
|
|
int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue); |
|
|
|
void php_json_parser_array_init(zval *object); |
|
|
|
void php_json_parser_array_append(zval *array, zval *zvalue); |
|
|
|
static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); |
|
|
|
static void php_json_yyerror(php_json_parser *parser, char const *msg); |
|
|
|
|
|
|
|
#define PHP_JSON_DEPTH_DEC --parser->depth |
|
|
|
#define PHP_JSON_DEPTH_INC \ |
|
|
|
if (parser->max_depth && parser->depth >= parser->max_depth) { \ |
|
|
|
parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \ |
|
|
|
YYERROR; \ |
|
|
|
} \ |
|
|
|
++parser->depth |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -514,10 +511,10 @@ static const yytype_uint8 yytranslate[] = |
|
|
|
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ |
|
|
|
static const yytype_uint8 yyrline[] = |
|
|
|
{ |
|
|
|
0, 92, 92, 98, 105, 105, 113, 114, 123, 126, |
|
|
|
130, 136, 142, 149, 154, 161, 161, 169, 170, 179, |
|
|
|
182, 186, 191, 196, 203, 204, 208, 209, 210, 211, |
|
|
|
212, 213, 214, 215, 216, 217, 221 |
|
|
|
0, 89, 89, 95, 103, 102, 120, 121, 130, 133, |
|
|
|
137, 144, 151, 158, 163, 171, 170, 188, 189, 198, |
|
|
|
201, 205, 210, 215, 222, 223, 227, 228, 229, 230, |
|
|
|
231, 232, 233, 234, 235, 236, 240 |
|
|
|
}; |
|
|
|
#endif |
|
|
|
|
|
|
@ -1465,15 +1462,23 @@ yyreduce: |
|
|
|
|
|
|
|
case 4: |
|
|
|
|
|
|
|
{ PHP_JSON_DEPTH_INC; } |
|
|
|
{ |
|
|
|
PHP_JSON_DEPTH_INC; |
|
|
|
if (parser->methods.object_start && FAILURE == parser->methods.object_start(parser)) { |
|
|
|
YYERROR; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 5: |
|
|
|
|
|
|
|
{ |
|
|
|
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-1].value)); |
|
|
|
PHP_JSON_DEPTH_DEC; |
|
|
|
(yyval.value) = (yyvsp[-1].value); |
|
|
|
if (parser->methods.object_end && FAILURE == parser->methods.object_end(parser, &(yyval.value))) { |
|
|
|
YYERROR; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@ -1490,7 +1495,7 @@ yyreduce: |
|
|
|
case 8: |
|
|
|
|
|
|
|
{ |
|
|
|
php_json_parser_object_init(parser, &(yyval.value)); |
|
|
|
parser->methods.object_create(parser, &(yyval.value)); |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@ -1498,9 +1503,10 @@ yyreduce: |
|
|
|
case 10: |
|
|
|
|
|
|
|
{ |
|
|
|
php_json_parser_object_init(parser, &(yyval.value)); |
|
|
|
if (php_json_parser_object_update(parser, &(yyval.value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) |
|
|
|
parser->methods.object_create(parser, &(yyval.value)); |
|
|
|
if (parser->methods.object_update(parser, &(yyval.value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) { |
|
|
|
YYERROR; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@ -1508,8 +1514,9 @@ yyreduce: |
|
|
|
case 11: |
|
|
|
|
|
|
|
{ |
|
|
|
if (php_json_parser_object_update(parser, &(yyvsp[-2].value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) |
|
|
|
if (parser->methods.object_update(parser, &(yyvsp[-2].value), (yyvsp[0].pair).key, &(yyvsp[0].pair).val) == FAILURE) { |
|
|
|
YYERROR; |
|
|
|
} |
|
|
|
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-2].value)); |
|
|
|
} |
|
|
|
|
|
|
@ -1542,15 +1549,23 @@ yyreduce: |
|
|
|
|
|
|
|
case 15: |
|
|
|
|
|
|
|
{ PHP_JSON_DEPTH_INC; } |
|
|
|
{ |
|
|
|
PHP_JSON_DEPTH_INC; |
|
|
|
if (parser->methods.array_start && FAILURE == parser->methods.array_start(parser)) { |
|
|
|
YYERROR; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 16: |
|
|
|
|
|
|
|
{ |
|
|
|
PHP_JSON_DEPTH_DEC; |
|
|
|
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-1].value)); |
|
|
|
PHP_JSON_DEPTH_DEC; |
|
|
|
if (parser->methods.array_end && FAILURE == parser->methods.array_end(parser, &(yyval.value))) { |
|
|
|
YYERROR; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@ -1567,7 +1582,7 @@ yyreduce: |
|
|
|
case 19: |
|
|
|
|
|
|
|
{ |
|
|
|
php_json_parser_array_init(&(yyval.value)); |
|
|
|
parser->methods.array_create(parser, &(yyval.value)); |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@ -1575,8 +1590,8 @@ yyreduce: |
|
|
|
case 21: |
|
|
|
|
|
|
|
{ |
|
|
|
php_json_parser_array_init(&(yyval.value)); |
|
|
|
php_json_parser_array_append(&(yyval.value), &(yyvsp[0].value)); |
|
|
|
parser->methods.array_create(parser, &(yyval.value)); |
|
|
|
parser->methods.array_append(parser, &(yyval.value), &(yyvsp[0].value)); |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@ -1584,7 +1599,7 @@ yyreduce: |
|
|
|
case 22: |
|
|
|
|
|
|
|
{ |
|
|
|
php_json_parser_array_append(&(yyvsp[-2].value), &(yyvsp[0].value)); |
|
|
|
parser->methods.array_append(parser, &(yyvsp[-2].value), &(yyvsp[0].value)); |
|
|
|
ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-2].value)); |
|
|
|
} |
|
|
|
|
|
|
@ -1839,30 +1854,27 @@ yyreturn: |
|
|
|
|
|
|
|
/* Functions */ |
|
|
|
|
|
|
|
void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth) |
|
|
|
static int php_json_parser_array_create(php_json_parser *parser, zval *array) |
|
|
|
{ |
|
|
|
memset(parser, 0, sizeof(php_json_parser)); |
|
|
|
php_json_scanner_init(&parser->scanner, str, str_len, options); |
|
|
|
parser->depth = 1; |
|
|
|
parser->max_depth = max_depth; |
|
|
|
parser->return_value = return_value; |
|
|
|
return array_init(array); |
|
|
|
} |
|
|
|
|
|
|
|
php_json_error_code php_json_parser_error_code(php_json_parser *parser) |
|
|
|
static int php_json_parser_array_append(php_json_parser *parser, zval *array, zval *zvalue) |
|
|
|
{ |
|
|
|
return parser->scanner.errcode; |
|
|
|
zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); |
|
|
|
return SUCCESS; |
|
|
|
} |
|
|
|
|
|
|
|
void php_json_parser_object_init(php_json_parser *parser, zval *object) |
|
|
|
static int php_json_parser_object_create(php_json_parser *parser, zval *object) |
|
|
|
{ |
|
|
|
if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) { |
|
|
|
array_init(object); |
|
|
|
return array_init(object); |
|
|
|
} else { |
|
|
|
object_init(object); |
|
|
|
return object_init(object); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue) |
|
|
|
static int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue) |
|
|
|
{ |
|
|
|
/* if JSON_OBJECT_AS_ARRAY is set */ |
|
|
|
if (Z_TYPE_P(object) == IS_ARRAY) { |
|
|
@ -1880,7 +1892,7 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st |
|
|
|
return FAILURE; |
|
|
|
} |
|
|
|
ZVAL_NEW_STR(&zkey, key); |
|
|
|
zend_std_write_property(object, &zkey, zvalue, NULL); |
|
|
|
zend_std_write_property(object, &zkey, zvalue, NULL); |
|
|
|
|
|
|
|
if (Z_REFCOUNTED_P(zvalue)) { |
|
|
|
Z_DELREF_P(zvalue); |
|
|
@ -1891,26 +1903,71 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st |
|
|
|
return SUCCESS; |
|
|
|
} |
|
|
|
|
|
|
|
void php_json_parser_array_init(zval *array) |
|
|
|
{ |
|
|
|
array_init(array); |
|
|
|
} |
|
|
|
|
|
|
|
void php_json_parser_array_append(zval *array, zval *zvalue) |
|
|
|
{ |
|
|
|
zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); |
|
|
|
} |
|
|
|
|
|
|
|
int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) |
|
|
|
static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) |
|
|
|
{ |
|
|
|
int token = php_json_scan(&parser->scanner); |
|
|
|
value->value = parser->scanner.value; |
|
|
|
return token; |
|
|
|
} |
|
|
|
|
|
|
|
void php_json_yyerror(php_json_parser *parser, char const *msg) |
|
|
|
static void php_json_yyerror(php_json_parser *parser, char const *msg) |
|
|
|
{ |
|
|
|
if (!parser->scanner.errcode) { |
|
|
|
parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser) |
|
|
|
{ |
|
|
|
return parser->scanner.errcode; |
|
|
|
} |
|
|
|
|
|
|
|
static const php_json_parser_methods default_parser_methods = |
|
|
|
{ |
|
|
|
php_json_parser_array_create, |
|
|
|
php_json_parser_array_append, |
|
|
|
NULL, |
|
|
|
NULL, |
|
|
|
php_json_parser_object_create, |
|
|
|
php_json_parser_object_update, |
|
|
|
NULL, |
|
|
|
NULL, |
|
|
|
}; |
|
|
|
|
|
|
|
PHP_JSON_API void php_json_parser_init_ex(php_json_parser *parser, |
|
|
|
zval *return_value, |
|
|
|
char *str, |
|
|
|
size_t str_len, |
|
|
|
int options, |
|
|
|
int max_depth, |
|
|
|
const php_json_parser_methods *parser_methods) |
|
|
|
{ |
|
|
|
memset(parser, 0, sizeof(php_json_parser)); |
|
|
|
php_json_scanner_init(&parser->scanner, str, str_len, options); |
|
|
|
parser->depth = 1; |
|
|
|
parser->max_depth = max_depth; |
|
|
|
parser->return_value = return_value; |
|
|
|
memcpy(&parser->methods, parser_methods, sizeof(php_json_parser_methods)); |
|
|
|
} |
|
|
|
|
|
|
|
PHP_JSON_API void php_json_parser_init(php_json_parser *parser, |
|
|
|
zval *return_value, |
|
|
|
char *str, |
|
|
|
size_t str_len, |
|
|
|
int options, |
|
|
|
int max_depth) |
|
|
|
{ |
|
|
|
php_json_parser_init_ex( |
|
|
|
parser, |
|
|
|
return_value, |
|
|
|
str, |
|
|
|
str_len, |
|
|
|
options, |
|
|
|
max_depth, |
|
|
|
&default_parser_methods); |
|
|
|
} |
|
|
|
|
|
|
|
PHP_JSON_API int php_json_parse(php_json_parser *parser) |
|
|
|
{ |
|
|
|
return php_json_yyparse(parser); |
|
|
|
} |