json_parser.y 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. %code top {
  2. /*
  3. +----------------------------------------------------------------------+
  4. | PHP Version 7 |
  5. +----------------------------------------------------------------------+
  6. | Copyright (c) 1997-2018 The PHP Group |
  7. +----------------------------------------------------------------------+
  8. | This source file is subject to version 3.01 of the PHP license, |
  9. | that is bundled with this package in the file LICENSE, and is |
  10. | available through the world-wide-web at the following url: |
  11. | http://www.php.net/license/3_01.txt |
  12. | If you did not receive a copy of the PHP license and are unable to |
  13. | obtain it through the world-wide-web, please send a note to |
  14. | license@php.net so we can mail you a copy immediately. |
  15. +----------------------------------------------------------------------+
  16. | Author: Jakub Zelenka <bukka@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "php.h"
  20. #include "php_json.h"
  21. #include "php_json_parser.h"
  22. #define YYDEBUG 0
  23. #if YYDEBUG
  24. int json_yydebug = 1;
  25. #endif
  26. #ifdef _MSC_VER
  27. #define YYMALLOC malloc
  28. #define YYFREE free
  29. #endif
  30. #define PHP_JSON_USE(uv) ((void) (uv))
  31. #define PHP_JSON_USE_1(uvr, uv1) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1)
  32. #define PHP_JSON_USE_2(uvr, uv1, uv2) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1); PHP_JSON_USE(uv2)
  33. #define PHP_JSON_DEPTH_DEC --parser->depth
  34. #define PHP_JSON_DEPTH_INC \
  35. if (parser->max_depth && parser->depth >= parser->max_depth) { \
  36. parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \
  37. YYERROR; \
  38. } \
  39. ++parser->depth
  40. }
  41. %pure-parser
  42. %name-prefix "php_json_yy"
  43. %lex-param { php_json_parser *parser }
  44. %parse-param { php_json_parser *parser }
  45. %union {
  46. zval value;
  47. struct {
  48. zend_string *key;
  49. zval val;
  50. } pair;
  51. }
  52. %token <value> PHP_JSON_T_NUL
  53. %token <value> PHP_JSON_T_TRUE
  54. %token <value> PHP_JSON_T_FALSE
  55. %token <value> PHP_JSON_T_INT
  56. %token <value> PHP_JSON_T_DOUBLE
  57. %token <value> PHP_JSON_T_STRING
  58. %token <value> PHP_JSON_T_ESTRING
  59. %token <value> PHP_JSON_T_EOI
  60. %token <value> PHP_JSON_T_ERROR
  61. %type <value> start object key value array errlex
  62. %type <value> members member elements element
  63. %type <pair> pair
  64. %destructor { zval_ptr_dtor_nogc(&$$); } <value>
  65. %destructor { zend_string_release_ex($$.key, 0); zval_ptr_dtor_nogc(&$$.val); } <pair>
  66. %code {
  67. static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);
  68. static void php_json_yyerror(php_json_parser *parser, char const *msg);
  69. }
  70. %% /* Rules */
  71. start:
  72. value PHP_JSON_T_EOI
  73. {
  74. ZVAL_COPY_VALUE(&$$, &$1);
  75. ZVAL_COPY_VALUE(parser->return_value, &$1);
  76. PHP_JSON_USE($2); YYACCEPT;
  77. }
  78. | value errlex
  79. {
  80. PHP_JSON_USE_2($$, $1, $2);
  81. }
  82. ;
  83. object:
  84. '{'
  85. {
  86. PHP_JSON_DEPTH_INC;
  87. if (parser->methods.object_start && FAILURE == parser->methods.object_start(parser)) {
  88. YYERROR;
  89. }
  90. }
  91. members object_end
  92. {
  93. ZVAL_COPY_VALUE(&$$, &$3);
  94. PHP_JSON_DEPTH_DEC;
  95. if (parser->methods.object_end && FAILURE == parser->methods.object_end(parser, &$$)) {
  96. YYERROR;
  97. }
  98. }
  99. ;
  100. object_end:
  101. '}'
  102. | ']'
  103. {
  104. parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
  105. YYERROR;
  106. }
  107. ;
  108. members:
  109. /* empty */
  110. {
  111. parser->methods.object_create(parser, &$$);
  112. }
  113. | member
  114. ;
  115. member:
  116. pair
  117. {
  118. parser->methods.object_create(parser, &$$);
  119. if (parser->methods.object_update(parser, &$$, $1.key, &$1.val) == FAILURE) {
  120. YYERROR;
  121. }
  122. }
  123. | member ',' pair
  124. {
  125. if (parser->methods.object_update(parser, &$1, $3.key, &$3.val) == FAILURE) {
  126. YYERROR;
  127. }
  128. ZVAL_COPY_VALUE(&$$, &$1);
  129. }
  130. | member errlex
  131. {
  132. PHP_JSON_USE_2($$, $1, $2);
  133. }
  134. ;
  135. pair:
  136. key ':' value
  137. {
  138. $$.key = Z_STR($1);
  139. ZVAL_COPY_VALUE(&$$.val, &$3);
  140. }
  141. | key errlex
  142. {
  143. PHP_JSON_USE_2($$, $1, $2);
  144. }
  145. ;
  146. array:
  147. '['
  148. {
  149. PHP_JSON_DEPTH_INC;
  150. if (parser->methods.array_start && FAILURE == parser->methods.array_start(parser)) {
  151. YYERROR;
  152. }
  153. }
  154. elements array_end
  155. {
  156. ZVAL_COPY_VALUE(&$$, &$3);
  157. PHP_JSON_DEPTH_DEC;
  158. if (parser->methods.array_end && FAILURE == parser->methods.array_end(parser, &$$)) {
  159. YYERROR;
  160. }
  161. }
  162. ;
  163. array_end:
  164. ']'
  165. | '}'
  166. {
  167. parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
  168. YYERROR;
  169. }
  170. ;
  171. elements:
  172. /* empty */
  173. {
  174. parser->methods.array_create(parser, &$$);
  175. }
  176. | element
  177. ;
  178. element:
  179. value
  180. {
  181. parser->methods.array_create(parser, &$$);
  182. parser->methods.array_append(parser, &$$, &$1);
  183. }
  184. | element ',' value
  185. {
  186. parser->methods.array_append(parser, &$1, &$3);
  187. ZVAL_COPY_VALUE(&$$, &$1);
  188. }
  189. | element errlex
  190. {
  191. PHP_JSON_USE_2($$, $1, $2);
  192. }
  193. ;
  194. key:
  195. PHP_JSON_T_STRING
  196. | PHP_JSON_T_ESTRING
  197. ;
  198. value:
  199. object
  200. | array
  201. | PHP_JSON_T_STRING
  202. | PHP_JSON_T_ESTRING
  203. | PHP_JSON_T_INT
  204. | PHP_JSON_T_DOUBLE
  205. | PHP_JSON_T_NUL
  206. | PHP_JSON_T_TRUE
  207. | PHP_JSON_T_FALSE
  208. | errlex
  209. ;
  210. errlex:
  211. PHP_JSON_T_ERROR
  212. {
  213. PHP_JSON_USE_1($$, $1);
  214. YYERROR;
  215. }
  216. ;
  217. %% /* Functions */
  218. static int php_json_parser_array_create(php_json_parser *parser, zval *array)
  219. {
  220. array_init(array);
  221. return SUCCESS;
  222. }
  223. static int php_json_parser_array_append(php_json_parser *parser, zval *array, zval *zvalue)
  224. {
  225. zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue);
  226. return SUCCESS;
  227. }
  228. static int php_json_parser_object_create(php_json_parser *parser, zval *object)
  229. {
  230. if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) {
  231. array_init(object);
  232. return SUCCESS;
  233. } else {
  234. return object_init(object);
  235. }
  236. }
  237. static int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue)
  238. {
  239. /* if JSON_OBJECT_AS_ARRAY is set */
  240. if (Z_TYPE_P(object) == IS_ARRAY) {
  241. zend_symtable_update(Z_ARRVAL_P(object), key, zvalue);
  242. } else {
  243. zval zkey;
  244. if (ZSTR_LEN(key) > 0 && ZSTR_VAL(key)[0] == '\0') {
  245. parser->scanner.errcode = PHP_JSON_ERROR_INVALID_PROPERTY_NAME;
  246. zend_string_release_ex(key, 0);
  247. zval_ptr_dtor_nogc(zvalue);
  248. zval_ptr_dtor_nogc(object);
  249. return FAILURE;
  250. }
  251. ZVAL_NEW_STR(&zkey, key);
  252. zend_std_write_property(object, &zkey, zvalue, NULL);
  253. Z_TRY_DELREF_P(zvalue);
  254. }
  255. zend_string_release_ex(key, 0);
  256. return SUCCESS;
  257. }
  258. static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
  259. {
  260. int token = php_json_scan(&parser->scanner);
  261. value->value = parser->scanner.value;
  262. return token;
  263. }
  264. static void php_json_yyerror(php_json_parser *parser, char const *msg)
  265. {
  266. if (!parser->scanner.errcode) {
  267. parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
  268. }
  269. }
  270. PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser)
  271. {
  272. return parser->scanner.errcode;
  273. }
  274. static const php_json_parser_methods default_parser_methods =
  275. {
  276. php_json_parser_array_create,
  277. php_json_parser_array_append,
  278. NULL,
  279. NULL,
  280. php_json_parser_object_create,
  281. php_json_parser_object_update,
  282. NULL,
  283. NULL,
  284. };
  285. PHP_JSON_API void php_json_parser_init_ex(php_json_parser *parser,
  286. zval *return_value,
  287. char *str,
  288. size_t str_len,
  289. int options,
  290. int max_depth,
  291. const php_json_parser_methods *parser_methods)
  292. {
  293. memset(parser, 0, sizeof(php_json_parser));
  294. php_json_scanner_init(&parser->scanner, str, str_len, options);
  295. parser->depth = 1;
  296. parser->max_depth = max_depth;
  297. parser->return_value = return_value;
  298. memcpy(&parser->methods, parser_methods, sizeof(php_json_parser_methods));
  299. }
  300. PHP_JSON_API void php_json_parser_init(php_json_parser *parser,
  301. zval *return_value,
  302. char *str,
  303. size_t str_len,
  304. int options,
  305. int max_depth)
  306. {
  307. php_json_parser_init_ex(
  308. parser,
  309. return_value,
  310. str,
  311. str_len,
  312. options,
  313. max_depth,
  314. &default_parser_methods);
  315. }
  316. PHP_JSON_API int php_json_parse(php_json_parser *parser)
  317. {
  318. return php_json_yyparse(parser);
  319. }