summaryrefslogtreecommitdiff
path: root/ext/json/json_parser.tab.c
diff options
context:
space:
mode:
authorJakub Zelenka <bukka@php.net>2016-02-28 17:45:53 +0000
committerJakub Zelenka <bukka@php.net>2016-04-10 15:35:41 +0100
commit72ccfda25aadf7eb225d7f899475e7d274bd1e72 (patch)
tree9b5a24e2e2cbbcc7c2b92c6f3c1ee24ca5e2ccab /ext/json/json_parser.tab.c
parent4e128978269dddfee2d1377a97241664194c4bb5 (diff)
downloadphp-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.c164
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);
+}