diff options
author | Jakub Zelenka <bukka@php.net> | 2016-02-28 17:45:53 +0000 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2016-04-10 15:35:41 +0100 |
commit | 72ccfda25aadf7eb225d7f899475e7d274bd1e72 (patch) | |
tree | 9b5a24e2e2cbbcc7c2b92c6f3c1ee24ca5e2ccab /ext/json/json_parser.tab.c | |
parent | 4e128978269dddfee2d1377a97241664194c4bb5 (diff) | |
download | php-git-72ccfda25aadf7eb225d7f899475e7d274bd1e72.tar.gz |
Add method hooking support to json parser
This commit is just a slight modification (renaming and some small
changes) of the patch that has been provided by Andrey Hristov.
It adds support for hooking of the json parser operations and
allows re-using of modified JSON parsing outside of json ext.
Diffstat (limited to 'ext/json/json_parser.tab.c')
-rw-r--r-- | ext/json/json_parser.tab.c | 164 |
1 files changed, 116 insertions, 48 deletions
diff --git a/ext/json/json_parser.tab.c b/ext/json/json_parser.tab.c index b01d031f14..7ad54e3b77 100644 --- a/ext/json/json_parser.tab.c +++ b/ext/json/json_parser.tab.c @@ -201,20 +201,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 +503,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, 81, 81, 87, 94, 94, 104, 105, 114, 117, + 121, 127, 133, 140, 145, 152, 152, 162, 163, 172, + 175, 179, 184, 189, 196, 197, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 214 }; #endif @@ -1465,15 +1454,17 @@ yyreduce: case 4: - { PHP_JSON_DEPTH_INC; } + { if (FAILURE == parser->methods->object_start(parser)) YYERROR; } break; case 5: { - PHP_JSON_DEPTH_DEC; (yyval.value) = (yyvsp[-1].value); + if (FAILURE == parser->methods->object_end(parser, &(yyval.value))) { + YYERROR; + } } break; @@ -1490,7 +1481,7 @@ yyreduce: case 8: { - php_json_parser_object_init(parser, &(yyval.value)); + parser->methods->object_create(parser, &(yyval.value)); } break; @@ -1498,8 +1489,8 @@ 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; } @@ -1508,7 +1499,7 @@ 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 +1533,17 @@ yyreduce: case 15: - { PHP_JSON_DEPTH_INC; } + { if (FAILURE == parser->methods->array_start(parser)) YYERROR; } break; case 16: { - PHP_JSON_DEPTH_DEC; ZVAL_COPY_VALUE(&(yyval.value), &(yyvsp[-1].value)); + if (FAILURE == parser->methods->array_end(parser, &(yyval.value))) { + YYERROR; + } } break; @@ -1567,7 +1560,7 @@ yyreduce: case 19: { - php_json_parser_array_init(&(yyval.value)); + parser->methods->array_create(parser, &(yyval.value)); } break; @@ -1575,8 +1568,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 +1577,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 +1832,37 @@ 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_array_start(php_json_parser *parser) +{ + return parser->methods->depth_increase(parser); +} + +static int php_json_parser_array_end(php_json_parser *parser, zval *object) +{ + return parser->methods->depth_decrease(parser); +} + +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) { @@ -1891,26 +1891,94 @@ int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_st return SUCCESS; } -void php_json_parser_array_init(zval *array) +static int php_json_parser_object_start(php_json_parser *parser) { - array_init(array); + return parser->methods->depth_increase(parser); } -void php_json_parser_array_append(zval *array, zval *zvalue) +static int php_json_parser_object_end(php_json_parser *parser, zval *object) { - zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue); + return parser->methods->depth_decrease(parser); } - -int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) + +static int php_json_parser_depth_increase(php_json_parser *parser) +{ + if (parser->max_depth && parser->depth >= parser->max_depth) { + parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; + return FAILURE; + } + ++parser->depth; + return SUCCESS; +} + +static int php_json_parser_depth_decrease(php_json_parser *parser) +{ + --parser->depth; + return SUCCESS; +} + +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_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, + php_json_parser_array_start, + php_json_parser_array_end, + php_json_parser_object_create, + php_json_parser_object_update, + php_json_parser_object_start, + php_json_parser_object_end, + php_json_parser_depth_increase, + php_json_parser_depth_decrease +}; + +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; + parser->methods = parser_methods; +} + +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); +} |