Annotation of embedaddon/php/ext/json/JSON_parser.c, revision 1.1.1.1

1.1       misho       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: #include <stdio.h>
                     30: #include "JSON_parser.h"
                     31: 
                     32: /* Windows defines IN for documentation */
                     33: #undef IN
                     34: 
                     35: #define true  1
                     36: #define false 0
                     37: #define __   -1     /* the universal error code */
                     38: 
                     39: /*
                     40:     Characters are mapped into these 31 character classes. This allows for
                     41:     a significant reduction in the size of the state transition table.
                     42: */
                     43: 
                     44: enum classes {
                     45:     C_SPACE,  /* space */
                     46:     C_WHITE,  /* other whitespace */
                     47:     C_LCURB,  /* {  */
                     48:     C_RCURB,  /* } */
                     49:     C_LSQRB,  /* [ */
                     50:     C_RSQRB,  /* ] */
                     51:     C_COLON,  /* : */
                     52:     C_COMMA,  /* , */
                     53:     C_QUOTE,  /* " */
                     54:     C_BACKS,  /* \ */
                     55:     C_SLASH,  /* / */
                     56:     C_PLUS,   /* + */
                     57:     C_MINUS,  /* - */
                     58:     C_POINT,  /* . */
                     59:     C_ZERO ,  /* 0 */
                     60:     C_DIGIT,  /* 123456789 */
                     61:     C_LOW_A,  /* a */
                     62:     C_LOW_B,  /* b */
                     63:     C_LOW_C,  /* c */
                     64:     C_LOW_D,  /* d */
                     65:     C_LOW_E,  /* e */
                     66:     C_LOW_F,  /* f */
                     67:     C_LOW_L,  /* l */
                     68:     C_LOW_N,  /* n */
                     69:     C_LOW_R,  /* r */
                     70:     C_LOW_S,  /* s */
                     71:     C_LOW_T,  /* t */
                     72:     C_LOW_U,  /* u */
                     73:     C_ABCDF,  /* ABCDF */
                     74:     C_E,      /* E */
                     75:     C_ETC,    /* everything else */
                     76:     NR_CLASSES
                     77: };
                     78: 
                     79: static const int ascii_class[128] = {
                     80: /*
                     81:     This array maps the 128 ASCII characters into character classes.
                     82:     The remaining Unicode characters should be mapped to C_ETC.
                     83:     Non-whitespace control characters are errors.
                     84: */
                     85:     __,      __,      __,      __,      __,      __,      __,      __,
                     86:     __,      C_WHITE, C_WHITE, __,      __,      C_WHITE, __,      __,
                     87:     __,      __,      __,      __,      __,      __,      __,      __,
                     88:     __,      __,      __,      __,      __,      __,      __,      __,
                     89: 
                     90:     C_SPACE, C_ETC,   C_QUOTE, C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
                     91:     C_ETC,   C_ETC,   C_ETC,   C_PLUS,  C_COMMA, C_MINUS, C_POINT, C_SLASH,
                     92:     C_ZERO,  C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
                     93:     C_DIGIT, C_DIGIT, C_COLON, C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
                     94: 
                     95:     C_ETC,   C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E,     C_ABCDF, C_ETC,
                     96:     C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
                     97:     C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
                     98:     C_ETC,   C_ETC,   C_ETC,   C_LSQRB, C_BACKS, C_RSQRB, C_ETC,   C_ETC,
                     99: 
                    100:     C_ETC,   C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC,
                    101:     C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_LOW_L, C_ETC,   C_LOW_N, C_ETC,
                    102:     C_ETC,   C_ETC,   C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC,   C_ETC,
                    103:     C_ETC,   C_ETC,   C_ETC,   C_LCURB, C_ETC,   C_RCURB, C_ETC,   C_ETC
                    104: };
                    105: 
                    106: 
                    107: /*
                    108:     The state codes.
                    109: */
                    110: enum states {
                    111:     GO,  /* start    */
                    112:     OK,  /* ok       */
                    113:     OB,  /* object   */
                    114:     KE,  /* key      */
                    115:     CO,  /* colon    */
                    116:     VA,  /* value    */
                    117:     AR,  /* array    */
                    118:     ST,  /* string   */
                    119:     ES,  /* escape   */
                    120:     U1,  /* u1       */
                    121:     U2,  /* u2       */
                    122:     U3,  /* u3       */
                    123:     U4,  /* u4       */
                    124:     MI,  /* minus    */
                    125:     ZE,  /* zero     */
                    126:     IN,  /* integer  */
                    127:     FR,  /* fraction */
                    128:     E1,  /* e        */
                    129:     E2,  /* ex       */
                    130:     E3,  /* exp      */
                    131:     T1,  /* tr       */
                    132:     T2,  /* tru      */
                    133:     T3,  /* true     */
                    134:     F1,  /* fa       */
                    135:     F2,  /* fal      */
                    136:     F3,  /* fals     */
                    137:     F4,  /* false    */
                    138:     N1,  /* nu       */
                    139:     N2,  /* nul      */
                    140:     N3,  /* null     */
                    141:     NR_STATES
                    142: };
                    143: 
                    144: 
                    145: static const int state_transition_table[NR_STATES][NR_CLASSES] = {
                    146: /*
                    147:     The state transition table takes the current state and the current symbol,
                    148:     and returns either a new state or an action. An action is represented as a
                    149:     negative number. A JSON text is accepted if at the end of the text the
                    150:     state is OK and if the mode is MODE_DONE.
                    151: 
                    152:                  white                                      1-9                                   ABCDF  etc
                    153:              space |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  |  a  b  c  d  e  f  l  n  r  s  t  u  |  E  |*/
                    154: /*start  GO*/ {GO,GO,-6,__,-5,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    155: /*ok     OK*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    156: /*object OB*/ {OB,OB,__,-9,__,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    157: /*key    KE*/ {KE,KE,__,__,__,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    158: /*colon  CO*/ {CO,CO,__,__,__,__,-2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    159: /*value  VA*/ {VA,VA,-6,__,-5,__,__,__,ST,__,__,__,MI,__,ZE,IN,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__},
                    160: /*array  AR*/ {AR,AR,-6,__,-5,-7,__,__,ST,__,__,__,MI,__,ZE,IN,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__},
                    161: /*string ST*/ {ST,__,ST,ST,ST,ST,ST,ST,-4,ES,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
                    162: /*escape ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__},
                    163: /*u1     U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__},
                    164: /*u2     U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__},
                    165: /*u3     U3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__},
                    166: /*u4     U4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ST,ST,ST,ST,ST,ST,ST,ST,__,__,__,__,__,__,ST,ST,__},
                    167: /*minus  MI*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IN,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    168: /*zero   ZE*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,FR,__,__,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
                    169: /*int    IN*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,FR,IN,IN,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
                    170: /*frac   FR*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
                    171: /*e      E1*/ {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    172: /*ex     E2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    173: /*exp    E3*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    174: /*tr     T1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__},
                    175: /*tru    T2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__},
                    176: /*true   T3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__},
                    177: /*fa     F1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
                    178: /*fal    F2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__},
                    179: /*fals   F3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__},
                    180: /*false  F4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__},
                    181: /*nu     N1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__},
                    182: /*nul    N2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__},
                    183: /*null   N3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__},
                    184: };
                    185: 
                    186: 
                    187: /*
                    188:     These modes can be pushed on the stack.
                    189: */
                    190: enum modes {
                    191:     MODE_ARRAY, 
                    192:     MODE_DONE,  
                    193:     MODE_KEY,   
                    194:     MODE_OBJECT,
                    195: };
                    196: 
                    197: 
                    198: /*
                    199:     Push a mode onto the stack. Return false if there is overflow.
                    200: */
                    201: static int
                    202: push(JSON_parser jp, int mode)
                    203: {
                    204:     jp->top += 1;
                    205:     if (jp->top >= jp->depth) {
                    206:                jp->error_code = PHP_JSON_ERROR_DEPTH;
                    207:         return false;
                    208:     }
                    209:     jp->stack[jp->top] = mode;
                    210:     return true;
                    211: }
                    212: 
                    213: 
                    214: /*
                    215:     Pop the stack, assuring that the current mode matches the expectation.
                    216:     Return false if there is underflow or if the modes mismatch.
                    217: */
                    218: static int
                    219: pop(JSON_parser jp, int mode)
                    220: {
                    221:     if (jp->top < 0 || jp->stack[jp->top] != mode) {
                    222:                jp->error_code = PHP_JSON_ERROR_STATE_MISMATCH;
                    223:         return false;
                    224:     }
                    225:     jp->top -= 1;
                    226:     return true;
                    227: }
                    228: 
                    229: /*
                    230:     new_JSON_checker starts the checking process by constructing a JSON_checker
                    231:     object. It takes a depth parameter that restricts the level of maximum
                    232:     nesting.
                    233: 
                    234:     To continue the process, call JSON_checker_char for each character in the
                    235:     JSON text, and then call JSON_checker_done to obtain the final result.
                    236:     These functions are fully reentrant.
                    237: 
                    238:     The JSON_checker object will be deleted by JSON_checker_done.
                    239:     JSON_checker_char will delete the JSON_checker object if it sees an error.
                    240: */
                    241: JSON_parser
                    242: new_JSON_parser(int depth)
                    243: {
                    244:     JSON_parser jp = (JSON_parser)emalloc(sizeof(struct JSON_parser_struct));
                    245:     jp->state = GO;
                    246:     jp->depth = depth;
                    247:     jp->top = -1;
                    248:        jp->error_code = PHP_JSON_ERROR_NONE;
                    249:     jp->stack = (int*)ecalloc(depth, sizeof(int));
                    250:     if (depth > JSON_PARSER_DEFAULT_DEPTH) {
                    251:         jp->the_zstack = (zval **)safe_emalloc(depth, sizeof(zval), 0);
                    252:     } else {
                    253:         jp->the_zstack = &jp->the_static_zstack[0];
                    254:     }
                    255:     push(jp, MODE_DONE);
                    256:     return jp;
                    257: }
                    258: 
                    259: /*
                    260:     Delete the JSON_parser object.
                    261: */
                    262: int
                    263: free_JSON_parser(JSON_parser jp)
                    264: {
                    265:     efree((void*)jp->stack);
                    266:     if (jp->the_zstack != &jp->the_static_zstack[0]) {
                    267:         efree(jp->the_zstack);
                    268:     }
                    269:     efree((void*)jp);
                    270:     return false;
                    271: }
                    272: 
                    273: static int dehexchar(char c)
                    274: {
                    275:     if (c >= '0' && c <= '9')
                    276:     {
                    277:         return c - '0';
                    278:     }
                    279:     else if (c >= 'A' && c <= 'F')
                    280:     {
                    281:         return c - ('A' - 10);
                    282:     }
                    283:     else if (c >= 'a' && c <= 'f')
                    284:     {
                    285:         return c - ('a' - 10);
                    286:     }
                    287:     else
                    288:     {
                    289:         return -1;
                    290:     }
                    291: }
                    292: 
                    293: 
                    294: static void json_create_zval(zval **z, smart_str *buf, int type)
                    295: {
                    296:     ALLOC_INIT_ZVAL(*z);
                    297: 
                    298:     if (type == IS_LONG)
                    299:     {
                    300:                if (buf->c[0] == '-') {
                    301:                        buf->len--;
                    302:                }
                    303: 
                    304:                if (buf->len >= MAX_LENGTH_OF_LONG - 1) {
                    305:                        if (buf->len == MAX_LENGTH_OF_LONG - 1) {
                    306:                                int cmp = strcmp(buf->c + (buf->c[0] == '-'), long_min_digits);
                    307: 
                    308:                                if (!(cmp < 0 || (cmp == 0 && buf->c[0] == '-'))) {
                    309:                                        goto use_double;
                    310:                                }
                    311:                        } else {
                    312:                                goto use_double;
                    313:                        }
                    314:                }
                    315: 
                    316:                ZVAL_LONG(*z, strtol(buf->c, NULL, 10));
                    317:     }
                    318:     else if (type == IS_DOUBLE)
                    319:     {
                    320: use_double:
                    321:         ZVAL_DOUBLE(*z, zend_strtod(buf->c, NULL));
                    322:     }
                    323:     else if (type == IS_STRING)
                    324:     {
                    325:         ZVAL_STRINGL(*z, buf->c, buf->len, 1);
                    326:     }
                    327:     else if (type == IS_BOOL)
                    328:     {
                    329:         ZVAL_BOOL(*z, (*(buf->c) == 't'));
                    330:     }
                    331:     else /* type == IS_NULL) || type unknown */
                    332:     {
                    333:         ZVAL_NULL(*z);
                    334:     }
                    335: }
                    336: 
                    337: 
                    338: static void utf16_to_utf8(smart_str *buf, unsigned short utf16)
                    339: {
                    340:     if (utf16 < 0x80)
                    341:     {
                    342:         smart_str_appendc(buf, (unsigned char) utf16);
                    343:     }
                    344:     else if (utf16 < 0x800)
                    345:     {
                    346:         smart_str_appendc(buf, 0xc0 | (utf16 >> 6));
                    347:         smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
                    348:     }
                    349:     else if ((utf16 & 0xfc00) == 0xdc00
                    350:                 && buf->len >= 3
                    351:                 && ((unsigned char) buf->c[buf->len - 3]) == 0xed
                    352:                 && ((unsigned char) buf->c[buf->len - 2] & 0xf0) == 0xa0
                    353:                 && ((unsigned char) buf->c[buf->len - 1] & 0xc0) == 0x80)
                    354:     {
                    355:         /* found surrogate pair */
                    356:         unsigned long utf32;
                    357: 
                    358:         utf32 = (((buf->c[buf->len - 2] & 0xf) << 16)
                    359:                     | ((buf->c[buf->len - 1] & 0x3f) << 10)
                    360:                     | (utf16 & 0x3ff)) + 0x10000;
                    361:         buf->len -= 3;
                    362: 
                    363:         smart_str_appendc(buf, (unsigned char) (0xf0 | (utf32 >> 18)));
                    364:         smart_str_appendc(buf, 0x80 | ((utf32 >> 12) & 0x3f));
                    365:         smart_str_appendc(buf, 0x80 | ((utf32 >> 6) & 0x3f));
                    366:         smart_str_appendc(buf, 0x80 | (utf32 & 0x3f));
                    367:     }
                    368:     else
                    369:     {
                    370:         smart_str_appendc(buf, 0xe0 | (utf16 >> 12));
                    371:         smart_str_appendc(buf, 0x80 | ((utf16 >> 6) & 0x3f));
                    372:         smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
                    373:     }
                    374: }
                    375: 
                    376: static void attach_zval(JSON_parser jp, int up, int cur, smart_str *key, int assoc TSRMLS_DC)
                    377: {
                    378:     zval *root = jp->the_zstack[up];
                    379:     zval *child =  jp->the_zstack[cur];
                    380:     int up_mode = jp->stack[up];
                    381: 
                    382:     if (up_mode == MODE_ARRAY)
                    383:     {
                    384:         add_next_index_zval(root, child);
                    385:     }
                    386:     else if (up_mode == MODE_OBJECT)
                    387:     {
                    388:         if (!assoc)
                    389:         {
                    390:             add_property_zval_ex(root, (key->len ? key->c : "_empty_"), (key->len ? (key->len + 1) : sizeof("_empty_")), child TSRMLS_CC);
                    391:             Z_DELREF_P(child);
                    392:         }
                    393:         else
                    394:         {
                    395:             add_assoc_zval_ex(root, (key->len ? key->c : ""), (key->len ? (key->len + 1) : sizeof("")), child);
                    396:         }
                    397:         key->len = 0;
                    398:     }
                    399: }
                    400: 
                    401: 
                    402: #define FREE_BUFFERS() smart_str_free(&buf); smart_str_free(&key);
                    403: #define SWAP_BUFFERS(from, to) do { \
                    404:         char *t1 = from.c; \
                    405:         int t2 = from.a; \
                    406:         from.c = to.c; \
                    407:         from.a = to.a; \
                    408:         to.c = t1; \
                    409:         to.a = t2; \
                    410:         to.len = from.len; \
                    411:         from.len = 0; \
                    412:         } while(0);
                    413: #define JSON_RESET_TYPE() type = -1;
                    414: 
                    415: /*
                    416:     The JSON_parser takes a UTF-16 encoded string and determines if it is a
                    417:     syntactically correct JSON text. Along the way, it creates a PHP variable.
                    418: 
                    419:     It is implemented as a Pushdown Automaton; that means it is a finite state
                    420:     machine with a stack.
                    421: */
                    422: int
                    423: parse_JSON(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, int assoc TSRMLS_DC)
                    424: {
                    425:     int next_char;  /* the next character */
                    426:     int next_class;  /* the next character class */
                    427:     int next_state;  /* the next state */
                    428:     int the_index;
                    429: 
                    430:     smart_str buf = {0};
                    431:     smart_str key = {0};
                    432: 
                    433:     unsigned short utf16 = 0;
                    434:     int type;
                    435: 
                    436:        JSON_RESET_TYPE();
                    437: 
                    438:     for (the_index = 0; the_index < length; the_index += 1) {
                    439:         next_char = utf16_json[the_index];
                    440:                if (next_char >= 128) {
                    441:                        next_class = C_ETC;
                    442:                } else {
                    443:                        next_class = ascii_class[next_char];
                    444:                        if (next_class <= __) {
                    445:                                jp->error_code = PHP_JSON_ERROR_CTRL_CHAR;
                    446:                                FREE_BUFFERS();
                    447:                                return false;
                    448:                        }
                    449:                }
                    450: /*
                    451:     Get the next state from the transition table.
                    452: */
                    453:         next_state = state_transition_table[jp->state][next_class];
                    454:         if (next_state >= 0) {
                    455: /*
                    456:     Change the state and iterate
                    457: */
                    458:                        if (type == IS_STRING) {
                    459:                    if (next_state == ST && jp->state != U4) {
                    460:                        if (jp->state != ES) {
                    461:                            utf16_to_utf8(&buf, next_char);
                    462:                        } else {
                    463:                            switch (next_char) {
                    464:                                case 'b':
                    465:                                    smart_str_appendc(&buf, '\b');
                    466:                                    break;
                    467:                                case 't':
                    468:                                    smart_str_appendc(&buf, '\t');
                    469:                                    break;
                    470:                                case 'n':
                    471:                                    smart_str_appendc(&buf, '\n');
                    472:                                    break;
                    473:                                case 'f':
                    474:                                    smart_str_appendc(&buf, '\f');
                    475:                                    break;
                    476:                                case 'r':
                    477:                                    smart_str_appendc(&buf, '\r');
                    478:                                    break;
                    479:                                default:
                    480:                                    utf16_to_utf8(&buf, next_char);
                    481:                                    break;
                    482:                            }
                    483:                        }
                    484:                    } else if (next_state == U2) {
                    485:                        utf16 = dehexchar(next_char) << 12;
                    486:                    } else if (next_state == U3) {
                    487:                        utf16 += dehexchar(next_char) << 8;
                    488:                    } else if (next_state == U4) {
                    489:                        utf16 += dehexchar(next_char) << 4;
                    490:                    } else if (next_state == ST && jp->state == U4) {
                    491:                        utf16 += dehexchar(next_char);
                    492:                        utf16_to_utf8(&buf, utf16);
                    493:                    }
                    494:                } else if (type < IS_LONG && (next_class == C_DIGIT || next_class == C_ZERO)) {
                    495:                    type = IS_LONG;
                    496:                    smart_str_appendc(&buf, next_char);
                    497:                } else if (type == IS_LONG && next_state == E1) {
                    498:                    type = IS_DOUBLE;
                    499:                    smart_str_appendc(&buf, next_char);
                    500:                } else if (type < IS_DOUBLE && next_class == C_POINT) {
                    501:                    type = IS_DOUBLE;
                    502:                    smart_str_appendc(&buf, next_char);
                    503:                } else if (type < IS_STRING && next_class == C_QUOTE) {
                    504:                    type = IS_STRING;
                    505:                } else if (type < IS_BOOL && ((jp->state == T3 && next_state == OK) || (jp->state == F4 && next_state == OK))) {
                    506:                    type = IS_BOOL;
                    507:                } else if (type < IS_NULL && jp->state == N3 && next_state == OK) {
                    508:                    type = IS_NULL;
                    509:                } else if (type != IS_STRING && next_class > C_WHITE) {
                    510:                    utf16_to_utf8(&buf, next_char);
                    511:                }
                    512:                jp->state = next_state;
                    513:                } else {
                    514: /*
                    515:     Perform one of the predefined actions.
                    516: */
                    517:             switch (next_state) {
                    518: /* empty } */
                    519:             case -9:
                    520:                 if (!pop(jp, MODE_KEY)) {
                    521:                     FREE_BUFFERS();
                    522:                     return false;
                    523:                 }
                    524:                 jp->state = OK;
                    525:                 break;
                    526: /* } */
                    527:             case -8:
                    528:                 if (type != -1 && jp->stack[jp->top] == MODE_OBJECT)
                    529:                 {
                    530:                     zval *mval;
                    531:                     smart_str_0(&buf);
                    532: 
                    533:                     json_create_zval(&mval, &buf, type);
                    534: 
                    535:                     if (!assoc) {
                    536:                         add_property_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
                    537:                         Z_DELREF_P(mval);
                    538:                     } else {
                    539:                         add_assoc_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
                    540:                     }
                    541:                     key.len = 0;
                    542:                     buf.len = 0;
                    543:                     JSON_RESET_TYPE();
                    544:                 }
                    545: 
                    546: 
                    547:                 if (!pop(jp, MODE_OBJECT)) {
                    548:                     FREE_BUFFERS();
                    549:                     return false;
                    550:                 }
                    551:                 jp->state = OK;
                    552:                 break;
                    553: /* ] */
                    554:             case -7:
                    555:             {
                    556:                 if (type != -1 && jp->stack[jp->top] == MODE_ARRAY)
                    557:                 {
                    558:                     zval *mval;
                    559:                     smart_str_0(&buf);
                    560: 
                    561:                     json_create_zval(&mval, &buf, type);
                    562:                     add_next_index_zval(jp->the_zstack[jp->top], mval);
                    563:                     buf.len = 0;
                    564:                     JSON_RESET_TYPE();
                    565:                 }
                    566: 
                    567:                 if (!pop(jp, MODE_ARRAY)) {
                    568:                     FREE_BUFFERS();
                    569:                     return false;
                    570:                 }
                    571:                 jp->state = OK;
                    572:             }
                    573:                        break;
                    574: /* { */
                    575:             case -6:
                    576:                 if (!push(jp, MODE_KEY)) {
                    577:                     FREE_BUFFERS();
                    578:                     return false;
                    579:                 }
                    580: 
                    581:                 jp->state = OB;
                    582:                 if (jp->top > 0) {
                    583:                     zval *obj;
                    584: 
                    585:                     if (jp->top == 1) {
                    586:                         obj = z;
                    587:                        } else {
                    588:                         ALLOC_INIT_ZVAL(obj);
                    589:                     }
                    590: 
                    591:                     if (!assoc) {
                    592:                         object_init(obj);
                    593:                     } else {
                    594:                         array_init(obj);
                    595:                     }
                    596: 
                    597:                     jp->the_zstack[jp->top] = obj;
                    598: 
                    599:                     if (jp->top > 1) {
                    600:                         attach_zval(jp, jp->top - 1, jp->top, &key, assoc TSRMLS_CC);
                    601:                     }
                    602: 
                    603:                     JSON_RESET_TYPE();
                    604:                 }
                    605: 
                    606:                 break;
                    607: /* [ */
                    608:             case -5:
                    609:                 if (!push(jp, MODE_ARRAY)) {
                    610:                     FREE_BUFFERS();
                    611:                     return false;
                    612:                 }
                    613:                 jp->state = AR;
                    614: 
                    615:                 if (jp->top > 0) {
                    616:                     zval *arr;
                    617: 
                    618:                     if (jp->top == 1) {
                    619:                         arr = z;
                    620:                     } else {
                    621:                         ALLOC_INIT_ZVAL(arr);
                    622:                     }
                    623: 
                    624:                     array_init(arr);
                    625:                     jp->the_zstack[jp->top] = arr;
                    626: 
                    627:                     if (jp->top > 1) {
                    628:                         attach_zval(jp, jp->top - 1, jp->top, &key, assoc TSRMLS_CC);
                    629:                     }
                    630: 
                    631:                     JSON_RESET_TYPE();
                    632:                 }
                    633: 
                    634:                 break;
                    635: 
                    636: /* " */
                    637:             case -4:
                    638:                 switch (jp->stack[jp->top]) {
                    639:                 case MODE_KEY:
                    640:                     jp->state = CO;
                    641:                     smart_str_0(&buf);
                    642:                     SWAP_BUFFERS(buf, key);
                    643:                     JSON_RESET_TYPE();
                    644:                     break;
                    645:                 case MODE_ARRAY:
                    646:                 case MODE_OBJECT:
                    647:                     jp->state = OK;
                    648:                     break;
                    649:                                case MODE_DONE:
                    650:                                        if (type == IS_STRING) {
                    651:                                                smart_str_0(&buf);
                    652:                                                ZVAL_STRINGL(z, buf.c, buf.len, 1);
                    653:                                                jp->state = OK;
                    654:                                                break;
                    655:                                        }
                    656:                                        /* fall through if not IS_STRING */
                    657:                 default:
                    658:                     FREE_BUFFERS();
                    659:                     jp->error_code = PHP_JSON_ERROR_SYNTAX;
                    660:                     return false;
                    661:                 }
                    662:                 break;
                    663: /* , */
                    664:             case -3:
                    665:             {
                    666:                 zval *mval;
                    667: 
                    668:                 if (type != -1 &&
                    669:                     (jp->stack[jp->top] == MODE_OBJECT ||
                    670:                      jp->stack[jp->top] == MODE_ARRAY))
                    671:                 {
                    672:                     smart_str_0(&buf);
                    673:                     json_create_zval(&mval, &buf, type);
                    674:                 }
                    675: 
                    676:                 switch (jp->stack[jp->top]) {
                    677:                     case MODE_OBJECT:
                    678:                         if (pop(jp, MODE_OBJECT) && push(jp, MODE_KEY)) {
                    679:                             if (type != -1) {
                    680:                                 if (!assoc) {
                    681:                                     add_property_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC);
                    682:                                     Z_DELREF_P(mval);
                    683:                                 } else {
                    684:                                     add_assoc_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval);
                    685:                                 }
                    686:                                 key.len = 0;
                    687:                             }
                    688:                             jp->state = KE;
                    689:                         }
                    690:                         break;
                    691:                     case MODE_ARRAY:
                    692:                         if (type != -1) {
                    693:                             add_next_index_zval(jp->the_zstack[jp->top], mval);
                    694:                         }
                    695:                         jp->state = VA;
                    696:                         break;
                    697:                     default:
                    698:                         FREE_BUFFERS();
                    699:                         jp->error_code = PHP_JSON_ERROR_SYNTAX;
                    700:                         return false;
                    701:                 }
                    702:                 buf.len = 0;
                    703:                 JSON_RESET_TYPE();
                    704:             }
                    705:             break;
                    706: /* : */
                    707:             case -2:
                    708:                 if (pop(jp, MODE_KEY) && push(jp, MODE_OBJECT)) {
                    709:                     jp->state = VA;
                    710:                     break;
                    711:                 }
                    712: /*
                    713:     syntax error
                    714: */
                    715:             default:
                    716:                 {
                    717:                                        jp->error_code = PHP_JSON_ERROR_SYNTAX;
                    718:                     FREE_BUFFERS();
                    719:                     return false;
                    720:                 }
                    721:             }
                    722:         }
                    723:     }
                    724: 
                    725:     FREE_BUFFERS();
                    726:        if (jp->state == OK && pop(jp, MODE_DONE)) {
                    727:                return true;
                    728:        }
                    729: 
                    730:        jp->error_code = PHP_JSON_ERROR_SYNTAX;
                    731:        return false;
                    732: }
                    733: 
                    734: 
                    735: /*
                    736:  * Local variables:
                    737:  * tab-width: 4
                    738:  * c-basic-offset: 4
                    739:  * End:
                    740:  * vim600: noet sw=4 ts=4
                    741:  * vim<600: noet sw=4 ts=4
                    742:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>