1 : /* JSON_parser.c */
2 :
3 : /* 2005-12-30 */
4 :
5 : /*
6 : Copyright (c) 2005 JSON.org
7 :
8 : Permission is hereby granted, free of charge, to any person obtaining a copy
9 : of this software and associated documentation files (the "Software"), to deal
10 : in the Software without restriction, including without limitation the rights
11 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : copies of the Software, and to permit persons to whom the Software is
13 : furnished to do so, subject to the following conditions:
14 :
15 : The above copyright notice and this permission notice shall be included in all
16 : copies or substantial portions of the Software.
17 :
18 : The Software shall be used for Good, not Evil.
19 :
20 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 : SOFTWARE.
27 : */
28 :
29 :
30 : #include "JSON_parser.h"
31 : #include <stdio.h>
32 :
33 : #define true 1
34 : #define false 0
35 :
36 : /*
37 : Characters are mapped into these 32 symbol classes. This allows for
38 : significant reductions in the size of the state transition table.
39 : */
40 :
41 : /* error */
42 : #define S_ERR -1
43 :
44 : /* space */
45 : #define S_SPA 0
46 :
47 : /* other whitespace */
48 : #define S_WSP 1
49 :
50 : /* { */
51 : #define S_LBE 2
52 :
53 : /* } */
54 : #define S_RBE 3
55 :
56 : /* [ */
57 : #define S_LBT 4
58 :
59 : /* ] */
60 : #define S_RBT 5
61 :
62 : /* : */
63 : #define S_COL 6
64 :
65 : /* , */
66 : #define S_COM 7
67 :
68 : /* " */
69 : #define S_QUO 8
70 :
71 : /* \ */
72 : #define S_BAC 9
73 :
74 : /* / */
75 : #define S_SLA 10
76 :
77 : /* + */
78 : #define S_PLU 11
79 :
80 : /* - */
81 : #define S_MIN 12
82 :
83 : /* . */
84 : #define S_DOT 13
85 :
86 : /* 0 */
87 : #define S_ZER 14
88 :
89 : /* 123456789 */
90 : #define S_DIG 15
91 :
92 : /* a */
93 : #define S__A_ 16
94 :
95 : /* b */
96 : #define S__B_ 17
97 :
98 : /* c */
99 : #define S__C_ 18
100 :
101 : /* d */
102 : #define S__D_ 19
103 :
104 : /* e */
105 : #define S__E_ 20
106 :
107 : /* f */
108 : #define S__F_ 21
109 :
110 : /* l */
111 : #define S__L_ 22
112 :
113 : /* n */
114 : #define S__N_ 23
115 :
116 : /* r */
117 : #define S__R_ 24
118 :
119 : /* s */
120 : #define S__S_ 25
121 :
122 : /* t */
123 : #define S__T_ 26
124 :
125 : /* u */
126 : #define S__U_ 27
127 :
128 : /* ABCDF */
129 : #define S_A_F 28
130 :
131 : /* E */
132 : #define S_E 29
133 :
134 : /* everything else */
135 : #define S_ETC 30
136 :
137 :
138 : /*
139 : This table maps the 128 ASCII characters into the 32 character classes.
140 : The remaining Unicode characters should be mapped to S_ETC.
141 : */
142 : static const int ascii_class[128] = {
143 : S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
144 : S_ERR, S_WSP, S_WSP, S_ERR, S_ERR, S_WSP, S_ERR, S_ERR,
145 : S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
146 : S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
147 :
148 : S_SPA, S_ETC, S_QUO, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
149 : S_ETC, S_ETC, S_ETC, S_PLU, S_COM, S_MIN, S_DOT, S_SLA,
150 : S_ZER, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG,
151 : S_DIG, S_DIG, S_COL, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
152 :
153 : S_ETC, S_A_F, S_A_F, S_A_F, S_A_F, S_E , S_A_F, S_ETC,
154 : S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
155 : S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
156 : S_ETC, S_ETC, S_ETC, S_LBT, S_BAC, S_RBT, S_ETC, S_ETC,
157 :
158 : S_ETC, S__A_, S__B_, S__C_, S__D_, S__E_, S__F_, S_ETC,
159 : S_ETC, S_ETC, S_ETC, S_ETC, S__L_, S_ETC, S__N_, S_ETC,
160 : S_ETC, S_ETC, S__R_, S__S_, S__T_, S__U_, S_ETC, S_ETC,
161 : S_ETC, S_ETC, S_ETC, S_LBE, S_ETC, S_RBE, S_ETC, S_ETC
162 : };
163 :
164 :
165 : /*
166 : The state transition table takes the current state and the current symbol,
167 : and returns either a new state or an action. A new state is a number between
168 : 0 and 29. An action is a negative number between -1 and -9. A JSON text is
169 : accepted if the end of the text is in state 9 and mode is MODE_DONE.
170 : */
171 : static const int state_transition_table[30][31] = {
172 : /* 0*/ { 0, 0,-8,-1,-6,-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},
173 : /* 1*/ { 1, 1,-1,-9,-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},
174 : /* 2*/ { 2, 2,-8,-1,-6,-5,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1},
175 : /* 3*/ { 3,-1, 3, 3, 3, 3, 3, 3,-4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
176 : /* 4*/ {-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1, 3,-1, 3, 3,-1, 3, 5,-1,-1,-1},
177 : /* 5*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 6, 6, 6, 6, 6, 6, 6, 6,-1,-1,-1,-1,-1,-1, 6, 6,-1},
178 : /* 6*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 7, 7, 7, 7, 7, 7, 7, 7,-1,-1,-1,-1,-1,-1, 7, 7,-1},
179 : /* 7*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 8, 8, 8, 8, 8, 8, 8, 8,-1,-1,-1,-1,-1,-1, 8, 8,-1},
180 : /* 8*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3, 3,-1},
181 : /* 9*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
182 : /*10*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1},
183 : /*11*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1},
184 : /*12*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
185 : /*13*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
186 : /*14*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,-1,-1,-1,-1,-1,-1,-1,-1},
187 : /*15*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,-1,-1},
188 : /*16*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
189 : /*17*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,18,-1,-1,-1},
190 : /*18*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,-1,-1,-1,-1,-1,-1,-1,-1},
191 : /*19*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1},
192 : /*20*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
193 : /*21*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
194 : /*22*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,22,22,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1},
195 : /*23*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,23,23,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1},
196 : /*24*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,25,25,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
197 : /*25*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
198 : /*26*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
199 : /*27*/ {27,27,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
200 : /*28*/ {28,28,-8,-1,-6,-1,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1},
201 : /*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}
202 : };
203 :
204 : #define JSON_PARSER_MAX_DEPTH 512
205 :
206 :
207 : /*
208 : A stack maintains the states of nested structures.
209 : */
210 :
211 : typedef struct json_parser
212 : {
213 : int the_stack[JSON_PARSER_MAX_DEPTH];
214 : zval *the_zstack[JSON_PARSER_MAX_DEPTH];
215 : int the_top;
216 : } json_parser;
217 :
218 :
219 : /*
220 : These modes can be pushed on the PDA stack.
221 : */
222 : #define MODE_DONE 1
223 : #define MODE_KEY 2
224 : #define MODE_OBJECT 3
225 : #define MODE_ARRAY 4
226 :
227 : /*
228 : Push a mode onto the stack. Return false if there is overflow.
229 : */
230 : static int
231 : push(json_parser *json, zval *z, int mode)
232 2064 : {
233 2064 : json->the_top += 1;
234 2064 : if (json->the_top >= JSON_PARSER_MAX_DEPTH) {
235 2 : return false;
236 : }
237 :
238 2062 : json->the_stack[json->the_top] = mode;
239 2062 : return true;
240 : }
241 :
242 :
243 : /*
244 : Pop the stack, assuring that the current mode matches the expectation.
245 : Return false if there is underflow or if the modes mismatch.
246 : */
247 : static int
248 : pop(json_parser *json, zval *z, int mode)
249 925 : {
250 925 : if (json->the_top < 0 || json->the_stack[json->the_top] != mode) {
251 5 : return false;
252 : }
253 920 : json->the_stack[json->the_top] = 0;
254 920 : json->the_top -= 1;
255 :
256 920 : return true;
257 : }
258 :
259 :
260 : static int dehexchar(char c)
261 600 : {
262 600 : if (c >= '0' && c <= '9')
263 : {
264 261 : return c - '0';
265 : }
266 339 : else if (c >= 'A' && c <= 'F')
267 : {
268 88 : return c - ('A' - 10);
269 : }
270 251 : else if (c >= 'a' && c <= 'f')
271 : {
272 251 : return c - ('a' - 10);
273 : }
274 : else
275 : {
276 0 : return -1;
277 : }
278 : }
279 :
280 :
281 : static void json_create_zval(zval **z, smart_str *buf, int type)
282 546 : {
283 546 : ALLOC_INIT_ZVAL(*z);
284 :
285 546 : if (type == IS_LONG)
286 : {
287 208 : if (buf->c[0] == '-') {
288 8 : buf->len--;
289 : }
290 :
291 208 : if (buf->len >= MAX_LENGTH_OF_LONG - 1) {
292 10 : if (buf->len == MAX_LENGTH_OF_LONG - 1) {
293 8 : int cmp = strcmp(buf->c + (buf->c[0] == '-'), long_min_digits);
294 :
295 8 : if (!(cmp < 0 || (cmp == 0 && buf->c[0] == '-'))) {
296 : goto use_double;
297 : }
298 : } else {
299 2 : goto use_double;
300 : }
301 : }
302 :
303 206 : ZVAL_LONG(*z, strtol(buf->c, NULL, 10));
304 : }
305 338 : else if (type == IS_DOUBLE)
306 : {
307 61 : use_double:
308 61 : ZVAL_DOUBLE(*z, zend_strtod(buf->c, NULL));
309 : }
310 279 : else if (type == IS_STRING)
311 : {
312 223 : ZVAL_STRINGL(*z, buf->c, buf->len, 1);
313 : }
314 56 : else if (type == IS_BOOL)
315 : {
316 38 : ZVAL_BOOL(*z, (*(buf->c) == 't'));
317 : }
318 : else /* type == IS_NULL) || type unknown */
319 : {
320 18 : ZVAL_NULL(*z);
321 : }
322 546 : }
323 :
324 :
325 : static void utf16_to_utf8(smart_str *buf, unsigned short utf16)
326 6790 : {
327 6790 : if (utf16 < 0x80)
328 : {
329 6620 : smart_str_appendc(buf, (unsigned char) utf16);
330 : }
331 170 : else if (utf16 < 0x800)
332 : {
333 8 : smart_str_appendc(buf, 0xc0 | (utf16 >> 6));
334 8 : smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
335 : }
336 163 : else if ((utf16 & 0xfc00) == 0xdc00
337 : && buf->len >= 3
338 : && ((unsigned char) buf->c[buf->len - 3]) == 0xed
339 : && ((unsigned char) buf->c[buf->len - 2] & 0xf0) == 0xa0
340 : && ((unsigned char) buf->c[buf->len - 1] & 0xc0) == 0x80)
341 : {
342 : /* found surrogate pair */
343 : unsigned long utf32;
344 :
345 1 : utf32 = (((buf->c[buf->len - 2] & 0xf) << 16)
346 : | ((buf->c[buf->len - 1] & 0x3f) << 10)
347 : | (utf16 & 0x3ff)) + 0x10000;
348 1 : buf->len -= 3;
349 :
350 1 : smart_str_appendc(buf, 0xf0 | (utf32 >> 18));
351 1 : smart_str_appendc(buf, 0x80 | ((utf32 >> 12) & 0x3f));
352 1 : smart_str_appendc(buf, 0x80 | ((utf32 >> 6) & 0x3f));
353 1 : smart_str_appendc(buf, 0x80 | (utf32 & 0x3f));
354 : }
355 : else
356 : {
357 161 : smart_str_appendc(buf, 0xe0 | (utf16 >> 12));
358 161 : smart_str_appendc(buf, 0x80 | ((utf16 >> 6) & 0x3f));
359 161 : smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
360 : }
361 6790 : }
362 :
363 : static void attach_zval(json_parser *json, int up, int cur, smart_str *key, int assoc TSRMLS_DC)
364 1193 : {
365 1193 : zval *root = json->the_zstack[up];
366 1193 : zval *child = json->the_zstack[cur];
367 1193 : int up_mode = json->the_stack[up];
368 :
369 1193 : if (up_mode == MODE_ARRAY)
370 : {
371 1124 : add_next_index_zval(root, child);
372 : }
373 69 : else if (up_mode == MODE_OBJECT)
374 : {
375 69 : if (!assoc)
376 : {
377 37 : add_property_zval_ex(root, (key->len ? key->c : "_empty_"), (key->len ? (key->len + 1) : sizeof("_empty_")), child TSRMLS_CC);
378 : #if PHP_MAJOR_VERSION >= 5
379 37 : ZVAL_DELREF(child);
380 : #endif
381 : }
382 : else
383 : {
384 32 : add_assoc_zval_ex(root, (key->len ? key->c : ""), (key->len ? (key->len + 1) : sizeof("")), child);
385 : }
386 69 : key->len = 0;
387 : }
388 1193 : }
389 :
390 :
391 : #define FREE_BUFFERS() do { smart_str_free(&buf); smart_str_free(&key); } while (0);
392 : #define SWAP_BUFFERS(from, to) do { \
393 : char *t1 = from.c; \
394 : int t2 = from.a; \
395 : from.c = to.c; \
396 : from.a = to.a; \
397 : to.c = t1; \
398 : to.a = t2; \
399 : to.len = from.len; \
400 : from.len = 0; \
401 : } while(0);
402 : #define JSON_RESET_TYPE() do { type = -1; } while(0);
403 : #define JSON(x) the_json.x
404 :
405 :
406 : /*
407 : The JSON_parser takes a UTF-16 encoded string and determines if it is a
408 : syntactically correct JSON text. Along the way, it creates a PHP variable.
409 :
410 : It is implemented as a Pushdown Automaton; that means it is a finite state
411 : machine with a stack.
412 : */
413 : int
414 : JSON_parser(zval *z, unsigned short p[], int length, int assoc TSRMLS_DC)
415 129 : {
416 : int b; /* the next character */
417 : int c; /* the next character class */
418 : int s; /* the next state */
419 : json_parser the_json; /* the parser state */
420 129 : int the_state = 0;
421 : int the_index;
422 :
423 129 : smart_str buf = {0};
424 129 : smart_str key = {0};
425 :
426 129 : int type = -1;
427 129 : unsigned short utf16 = 0;
428 :
429 129 : JSON(the_top) = -1;
430 129 : push(&the_json, z, MODE_DONE);
431 :
432 13895 : for (the_index = 0; the_index < length; the_index += 1) {
433 13842 : b = p[the_index];
434 13842 : if ((b & 127) == b) {
435 13817 : c = ascii_class[b];
436 13817 : if (c <= S_ERR) {
437 0 : FREE_BUFFERS();
438 0 : return false;
439 : }
440 : } else {
441 25 : c = S_ETC;
442 : }
443 : /*
444 : Get the next state from the transition table.
445 : */
446 13842 : s = state_transition_table[the_state][c];
447 13842 : if (s < 0) {
448 : /*
449 : Perform one of the predefined actions.
450 : */
451 3074 : switch (s) {
452 : /*
453 : empty }
454 : */
455 : case -9:
456 14 : if (!pop(&the_json, z, MODE_KEY)) {
457 0 : FREE_BUFFERS();
458 0 : return false;
459 : }
460 14 : the_state = 9;
461 14 : break;
462 : /*
463 : {
464 : */
465 : case -8:
466 88 : if (!push(&the_json, z, MODE_KEY)) {
467 0 : FREE_BUFFERS();
468 0 : return false;
469 : }
470 :
471 88 : the_state = 1;
472 88 : if (JSON(the_top) > 0)
473 : {
474 : zval *obj;
475 :
476 88 : if (JSON(the_top) == 1)
477 : {
478 39 : obj = z;
479 : }
480 : else
481 : {
482 49 : ALLOC_INIT_ZVAL(obj);
483 : }
484 :
485 88 : if (!assoc)
486 : {
487 50 : object_init(obj);
488 : }
489 : else
490 : {
491 38 : array_init(obj);
492 : }
493 :
494 88 : JSON(the_zstack)[JSON(the_top)] = obj;
495 :
496 88 : if (JSON(the_top) > 1)
497 : {
498 49 : attach_zval(&the_json, JSON(the_top-1), JSON(the_top), &key, assoc TSRMLS_CC);
499 : }
500 :
501 88 : JSON_RESET_TYPE();
502 : }
503 :
504 88 : break;
505 : /*
506 : }
507 : */
508 : case -7:
509 54 : if (type != -1 && JSON(the_stack)[JSON(the_top)] == MODE_OBJECT)
510 : {
511 : zval *mval;
512 26 : smart_str_0(&buf);
513 :
514 26 : json_create_zval(&mval, &buf, type);
515 :
516 26 : if (!assoc)
517 : {
518 14 : add_property_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
519 : #if PHP_MAJOR_VERSION >= 5
520 14 : ZVAL_DELREF(mval);
521 : #endif
522 : }
523 : else
524 : {
525 12 : add_assoc_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
526 : }
527 26 : key.len = 0;
528 26 : buf.len = 0;
529 26 : JSON_RESET_TYPE();
530 : }
531 :
532 :
533 54 : if (!pop(&the_json, z, MODE_OBJECT)) {
534 0 : FREE_BUFFERS();
535 0 : return false;
536 : }
537 54 : the_state = 9;
538 54 : break;
539 : /*
540 : [
541 : */
542 : case -6:
543 1193 : if (!push(&the_json, z, MODE_ARRAY)) {
544 2 : FREE_BUFFERS();
545 2 : return false;
546 : }
547 1191 : the_state = 2;
548 :
549 1191 : if (JSON(the_top) > 0)
550 : {
551 : zval *arr;
552 :
553 1191 : if (JSON(the_top) == 1)
554 : {
555 47 : arr = z;
556 : }
557 : else
558 : {
559 1144 : ALLOC_INIT_ZVAL(arr);
560 : }
561 :
562 1191 : array_init(arr);
563 1191 : JSON(the_zstack)[JSON(the_top)] = arr;
564 :
565 1191 : if (JSON(the_top) > 1)
566 : {
567 1144 : attach_zval(&the_json, JSON(the_top-1), JSON(the_top), &key, assoc TSRMLS_CC);
568 : }
569 :
570 1191 : JSON_RESET_TYPE();
571 : }
572 :
573 1191 : break;
574 : /*
575 : ]
576 : */
577 : case -5:
578 : {
579 151 : if (type != -1 && JSON(the_stack)[JSON(the_top)] == MODE_ARRAY)
580 : {
581 : zval *mval;
582 55 : smart_str_0(&buf);
583 :
584 55 : json_create_zval(&mval, &buf, type);
585 55 : add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
586 55 : buf.len = 0;
587 55 : JSON_RESET_TYPE();
588 : }
589 :
590 151 : if (!pop(&the_json, z, MODE_ARRAY)) {
591 2 : FREE_BUFFERS();
592 2 : return false;
593 : }
594 149 : the_state = 9;
595 : }
596 149 : break;
597 : /*
598 : "
599 : */
600 : case -4:
601 605 : switch (JSON(the_stack)[JSON(the_top)]) {
602 : case MODE_KEY:
603 364 : the_state = 27;
604 364 : smart_str_0(&buf);
605 364 : SWAP_BUFFERS(buf, key);
606 364 : JSON_RESET_TYPE();
607 364 : break;
608 : case MODE_ARRAY:
609 : case MODE_OBJECT:
610 228 : the_state = 9;
611 228 : break;
612 : case MODE_DONE:
613 13 : if (type == IS_STRING) {
614 13 : smart_str_0(&buf);
615 13 : ZVAL_STRINGL(z, buf.c, buf.len, 1);
616 13 : the_state = 9;
617 13 : break;
618 : }
619 : /* fall through if not IS_STRING */
620 : default:
621 0 : FREE_BUFFERS();
622 0 : return false;
623 : }
624 605 : break;
625 : /*
626 : ,
627 : */
628 : case -3:
629 : {
630 : zval *mval;
631 :
632 539 : if (type != -1 &&
633 : (JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
634 : JSON(the_stack[JSON(the_top)]) == MODE_ARRAY))
635 : {
636 465 : smart_str_0(&buf);
637 465 : json_create_zval(&mval, &buf, type);
638 : }
639 :
640 539 : switch (JSON(the_stack)[JSON(the_top)]) {
641 : case MODE_OBJECT:
642 294 : if (pop(&the_json, z, MODE_OBJECT) && push(&the_json, z, MODE_KEY)) {
643 294 : if (type != -1)
644 : {
645 254 : if (!assoc)
646 : {
647 126 : add_property_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
648 : #if PHP_MAJOR_VERSION >= 5
649 126 : ZVAL_DELREF(mval);
650 : #endif
651 : }
652 : else
653 : {
654 128 : add_assoc_zval_ex(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
655 : }
656 254 : key.len = 0;
657 : }
658 294 : the_state = 29;
659 : }
660 294 : break;
661 : case MODE_ARRAY:
662 243 : if (type != -1)
663 : {
664 211 : add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
665 : }
666 243 : the_state = 28;
667 243 : break;
668 : default:
669 2 : FREE_BUFFERS();
670 2 : return false;
671 : }
672 537 : buf.len = 0;
673 537 : JSON_RESET_TYPE();
674 : }
675 537 : break;
676 : /*
677 : :
678 : */
679 : case -2:
680 360 : if (pop(&the_json, z, MODE_KEY) && push(&the_json, z, MODE_OBJECT)) {
681 360 : the_state = 28;
682 360 : break;
683 : }
684 : /*
685 : syntax error
686 : */
687 : case -1:
688 : {
689 70 : FREE_BUFFERS();
690 70 : return false;
691 : }
692 : }
693 : } else {
694 : /*
695 : Change the state and iterate.
696 : */
697 10768 : if (type == IS_STRING)
698 : {
699 13076 : if (s == 3 && the_state != 8)
700 : {
701 5962 : if (the_state != 4)
702 : {
703 5751 : utf16_to_utf8(&buf, b);
704 : }
705 : else
706 : {
707 211 : switch (b)
708 : {
709 : case 'b':
710 16 : smart_str_appendc(&buf, '\b');
711 16 : break;
712 : case 't':
713 16 : smart_str_appendc(&buf, '\t');
714 16 : break;
715 : case 'n':
716 18 : smart_str_appendc(&buf, '\n');
717 18 : break;
718 : case 'f':
719 16 : smart_str_appendc(&buf, '\f');
720 16 : break;
721 : case 'r':
722 18 : smart_str_appendc(&buf, '\r');
723 18 : break;
724 : default:
725 127 : utf16_to_utf8(&buf, b);
726 : break;
727 : }
728 : }
729 : }
730 1152 : else if (s == 6)
731 : {
732 150 : utf16 = dehexchar(b) << 12;
733 : }
734 1002 : else if (s == 7)
735 : {
736 150 : utf16 += dehexchar(b) << 8;
737 : }
738 852 : else if (s == 8)
739 : {
740 150 : utf16 += dehexchar(b) << 4;
741 : }
742 702 : else if (s == 3 && the_state == 8)
743 : {
744 150 : utf16 += dehexchar(b);
745 150 : utf16_to_utf8(&buf, utf16);
746 : }
747 : }
748 3927 : else if (type < IS_LONG && (c == S_DIG || c == S_ZER))
749 : {
750 273 : type = IS_LONG;
751 273 : smart_str_appendc(&buf, b);
752 : }
753 3387 : else if (type == IS_LONG && s == 24)
754 : {
755 6 : type = IS_DOUBLE;
756 6 : smart_str_appendc(&buf, b);
757 : }
758 3428 : else if (type < IS_DOUBLE && c == S_DOT)
759 : {
760 53 : type = IS_DOUBLE;
761 53 : smart_str_appendc(&buf, b);
762 : }
763 3934 : else if (type < IS_STRING && c == S_QUO)
764 : {
765 612 : type = IS_STRING;
766 : }
767 2748 : else if (type < IS_BOOL && ((the_state == 12 && s == 9) || (the_state == 16 && s == 9)))
768 : {
769 38 : type = IS_BOOL;
770 : }
771 2690 : else if (type < IS_NULL && the_state == 19 && s == 9)
772 : {
773 18 : type = IS_NULL;
774 : }
775 2654 : else if (type != IS_STRING && c > S_WSP)
776 : {
777 762 : utf16_to_utf8(&buf, b);
778 : }
779 :
780 10768 : the_state = s;
781 : }
782 : }
783 :
784 53 : FREE_BUFFERS();
785 :
786 53 : return the_state == 9 && pop(&the_json, z, MODE_DONE);
787 : }
788 :
789 :
790 : /*
791 : * Local variables:
792 : * tab-width: 4
793 : * c-basic-offset: 4
794 : * End:
795 : * vim600: noet sw=4 ts=4
796 : * vim<600: noet sw=4 ts=4
797 : */
|