source: trunk/libtransmission/JSON_parser.c @ 10492

Last change on this file since 10492 was 10492, checked in by charles, 12 years ago

(trunk libT) update our JSON_parser snapshot

File size: 31.8 KB
Line 
1/*
2Copyright (c) 2005 JSON.org
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14The Software shall be used for Good, not Evil.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25/*
26    Callbacks, comments, Unicode handling by Jean Gressmann (jean@0x42.de), 2007-2010.
27   
28    Changelog:
29        2010-03-25
30            Fixed buffer overrun in grow_parse_buffer & cleaned up code.
31           
32        2009-10-19
33            Replaced long double in JSON_value_struct with double after reports
34            of strtold being broken on some platforms (charles@transmissionbt.com).
35           
36        2009-05-17
37            Incorporated benrudiak@googlemail.com fix for UTF16 decoding.
38           
39        2009-05-14
40            Fixed float parsing bug related to a locale being set that didn't
41            use '.' as decimal point character (charles@transmissionbt.com).
42           
43        2008-10-14
44            Renamed states.IN to states.IT to avoid name clash which IN macro
45            defined in windef.h (alexey.pelykh@gmail.com)
46           
47        2008-07-19
48            Removed some duplicate code & debugging variable (charles@transmissionbt.com)
49       
50        2008-05-28
51            Made JSON_value structure ansi C compliant. This bug was report by
52            trisk@acm.jhu.edu
53       
54        2008-05-20
55            Fixed bug reported by charles@transmissionbt.com where the switching
56            from static to dynamic parse buffer did not copy the static parse
57            buffer's content.
58*/
59
60
61
62#include <assert.h>
63#include <ctype.h>
64#include <float.h>
65#include <stddef.h>
66#include <stdio.h>
67#include <stdlib.h>
68#include <string.h>
69#include <locale.h>
70
71#include <evutil.h> /* evutil_strtoll() */
72
73#include "JSON_parser.h"
74
75#ifdef _MSC_VER
76#   if _MSC_VER >= 1400 /* Visual Studio 2005 and up */
77#      pragma warning(disable:4996) /* unsecure sscanf */
78#      pragma warning(disable:4127) /* conditional expression is constant */
79#   endif
80#endif
81
82
83#define true  1
84#define false 0
85#define __   -1     /* the universal error code */
86
87/* values chosen so that the object size is approx equal to one page (4K) */
88#ifndef JSON_PARSER_STACK_SIZE
89#   define JSON_PARSER_STACK_SIZE 128
90#endif
91
92#ifndef JSON_PARSER_PARSE_BUFFER_SIZE
93#   define JSON_PARSER_PARSE_BUFFER_SIZE 3500
94#endif
95
96typedef unsigned short UTF16;
97
98struct JSON_parser_struct {
99    JSON_parser_callback callback;
100    void* ctx;
101    signed char state, before_comment_state, type, escaped, comment, allow_comments, handle_floats_manually;
102    UTF16 utf16_high_surrogate;
103    long depth;
104    long top;
105    signed char* stack;
106    long stack_capacity;
107    char decimal_point;
108    char* parse_buffer;
109    size_t parse_buffer_capacity;
110    size_t parse_buffer_count;
111    size_t comment_begin_offset;
112    signed char static_stack[JSON_PARSER_STACK_SIZE];
113    char static_parse_buffer[JSON_PARSER_PARSE_BUFFER_SIZE];
114};
115
116#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
117
118/*
119    Characters are mapped into these character classes. This allows for
120    a significant reduction in the size of the state transition table.
121*/
122
123
124
125enum classes {
126    C_SPACE,  /* space */
127    C_WHITE,  /* other whitespace */
128    C_LCURB,  /* {  */
129    C_RCURB,  /* } */
130    C_LSQRB,  /* [ */
131    C_RSQRB,  /* ] */
132    C_COLON,  /* : */
133    C_COMMA,  /* , */
134    C_QUOTE,  /* " */
135    C_BACKS,  /* \ */
136    C_SLASH,  /* / */
137    C_PLUS,   /* + */
138    C_MINUS,  /* - */
139    C_POINT,  /* . */
140    C_ZERO ,  /* 0 */
141    C_DIGIT,  /* 123456789 */
142    C_LOW_A,  /* a */
143    C_LOW_B,  /* b */
144    C_LOW_C,  /* c */
145    C_LOW_D,  /* d */
146    C_LOW_E,  /* e */
147    C_LOW_F,  /* f */
148    C_LOW_L,  /* l */
149    C_LOW_N,  /* n */
150    C_LOW_R,  /* r */
151    C_LOW_S,  /* s */
152    C_LOW_T,  /* t */
153    C_LOW_U,  /* u */
154    C_ABCDF,  /* ABCDF */
155    C_E,      /* E */
156    C_ETC,    /* everything else */
157    C_STAR,   /* * */   
158    NR_CLASSES
159};
160
161static const signed char ascii_class[128] = {
162/*
163    This array maps the 128 ASCII characters into character classes.
164    The remaining Unicode characters should be mapped to C_ETC.
165    Non-whitespace control characters are errors.
166*/
167    __,      __,      __,      __,      __,      __,      __,      __,
168    __,      C_WHITE, C_WHITE, __,      __,      C_WHITE, __,      __,
169    __,      __,      __,      __,      __,      __,      __,      __,
170    __,      __,      __,      __,      __,      __,      __,      __,
171
172    C_SPACE, C_ETC,   C_QUOTE, C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
173    C_ETC,   C_ETC,   C_STAR,   C_PLUS,  C_COMMA, C_MINUS, C_POINT, C_SLASH,
174    C_ZERO,  C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
175    C_DIGIT, C_DIGIT, C_COLON, C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
176
177    C_ETC,   C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E,     C_ABCDF, C_ETC,
178    C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
179    C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_ETC,
180    C_ETC,   C_ETC,   C_ETC,   C_LSQRB, C_BACKS, C_RSQRB, C_ETC,   C_ETC,
181
182    C_ETC,   C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC,
183    C_ETC,   C_ETC,   C_ETC,   C_ETC,   C_LOW_L, C_ETC,   C_LOW_N, C_ETC,
184    C_ETC,   C_ETC,   C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC,   C_ETC,
185    C_ETC,   C_ETC,   C_ETC,   C_LCURB, C_ETC,   C_RCURB, C_ETC,   C_ETC
186};
187
188
189/*
190    The state codes.
191*/
192enum states {
193    GO,  /* start    */
194    OK,  /* ok       */
195    OB,  /* object   */
196    KE,  /* key      */
197    CO,  /* colon    */
198    VA,  /* value    */
199    AR,  /* array    */
200    ST,  /* string   */
201    ES,  /* escape   */
202    U1,  /* u1       */
203    U2,  /* u2       */
204    U3,  /* u3       */
205    U4,  /* u4       */
206    MI,  /* minus    */
207    ZE,  /* zero     */
208    IT,  /* integer  */
209    FR,  /* fraction */
210    E1,  /* e        */
211    E2,  /* ex       */
212    E3,  /* exp      */
213    T1,  /* tr       */
214    T2,  /* tru      */
215    T3,  /* true     */
216    F1,  /* fa       */
217    F2,  /* fal      */
218    F3,  /* fals     */
219    F4,  /* false    */
220    N1,  /* nu       */
221    N2,  /* nul      */
222    N3,  /* null     */
223    C1,  /* /        */
224    C2,  /* / *     */
225    C3,  /* *        */
226    FX,  /* *.* *eE* */
227    D1,  /* second UTF-16 character decoding started by \ */
228    D2,  /* second UTF-16 character proceeded by u */
229    NR_STATES
230};
231
232enum actions
233{
234    CB = -10, /* comment begin */
235    CE = -11, /* comment end */
236    FA = -12, /* false */
237    TR = -13, /* false */
238    NU = -14, /* null */
239    DE = -15, /* double detected by exponent e E */
240    DF = -16, /* double detected by fraction . */
241    SB = -17, /* string begin */
242    MX = -18, /* integer detected by minus */
243    ZX = -19, /* integer detected by zero */
244    IX = -20, /* integer detected by 1-9 */
245    EX = -21, /* next char is escaped */
246    UC = -22  /* Unicode character read */
247};
248
249
250static const signed char state_transition_table[NR_STATES][NR_CLASSES] = {
251/*
252    The state transition table takes the current state and the current symbol,
253    and returns either a new state or an action. An action is represented as a
254    negative number. A JSON text is accepted if at the end of the text the
255    state is OK and if the mode is MODE_DONE.
256
257                 white                                      1-9                                   ABCDF  etc
258             space |  {  }  [  ]  :  ,  "  \  /  +  -  .  0  |  a  b  c  d  e  f  l  n  r  s  t  u  |  E  |  * */
259/*start  GO*/ {GO,GO,-6,__,-5,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
260/*ok     OK*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
261/*object OB*/ {OB,OB,__,-9,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
262/*key    KE*/ {KE,KE,__,__,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
263/*colon  CO*/ {CO,CO,__,__,__,__,-2,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
264/*value  VA*/ {VA,VA,-6,__,-5,__,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__},
265/*array  AR*/ {AR,AR,-6,__,-5,-7,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__},
266/*string ST*/ {ST,__,ST,ST,ST,ST,ST,ST,-4,EX,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
267/*escape ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__,__},
268/*u1     U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__},
269/*u2     U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__},
270/*u3     U3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__,__},
271/*u4     U4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,UC,UC,UC,UC,UC,UC,UC,UC,__,__,__,__,__,__,UC,UC,__,__},
272/*minus  MI*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IT,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
273/*zero   ZE*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
274/*int    IT*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,IT,IT,__,__,__,__,DE,__,__,__,__,__,__,__,__,DE,__,__},
275/*frac   FR*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__},
276/*e      E1*/ {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
277/*ex     E2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
278/*exp    E3*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
279/*tr     T1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__,__},
280/*tru    T2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__,__},
281/*true   T3*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__},
282/*fa     F1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
283/*fal    F2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__,__},
284/*fals   F3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__,__},
285/*false  F4*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__},
286/*nu     N1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__,__},
287/*nul    N2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__,__},
288/*null   N3*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__},
289/*/      C1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,C2},
290/*/*     C2*/ {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3},
291/**      C3*/ {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,CE,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3},
292/*_.     FX*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__},
293/*\      D1*/ {__,__,__,__,__,__,__,__,__,D2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
294/*\      D2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U1,__,__,__,__},
295};
296
297
298/*
299    These modes can be pushed on the stack.
300*/
301enum modes {
302    MODE_ARRAY = 1, 
303    MODE_DONE = 2, 
304    MODE_KEY = 3,   
305    MODE_OBJECT = 4
306};
307
308static int
309push(JSON_parser jc, int mode)
310{
311/*
312    Push a mode onto the stack. Return false if there is overflow.
313*/
314    jc->top += 1;
315    if (jc->depth < 0) {
316        if (jc->top >= jc->stack_capacity) {
317            size_t bytes_to_allocate;
318            jc->stack_capacity *= 2;
319            bytes_to_allocate = jc->stack_capacity * sizeof(jc->static_stack[0]);
320            if (jc->stack == &jc->static_stack[0]) {
321                jc->stack = (signed char*)malloc(bytes_to_allocate);
322                memcpy(jc->stack, jc->static_stack, sizeof(jc->static_stack));
323            } else {
324                jc->stack = (signed char*)realloc(jc->stack, bytes_to_allocate);
325            }
326        }
327    } else {
328        if (jc->top >= jc->depth) {
329            return false;
330        }
331    }
332   
333    jc->stack[jc->top] = (signed char)mode;
334    return true;
335}
336
337
338static int
339pop(JSON_parser jc, int mode)
340{
341/*
342    Pop the stack, assuring that the current mode matches the expectation.
343    Return false if there is underflow or if the modes mismatch.
344*/
345    if (jc->top < 0 || jc->stack[jc->top] != mode) {
346        return false;
347    }
348    jc->top -= 1;
349    return true;
350}
351
352
353#define parse_buffer_clear(jc) \
354    do {\
355        jc->parse_buffer_count = 0;\
356        jc->parse_buffer[0] = 0;\
357    } while (0)
358   
359#define parse_buffer_pop_back_char(jc)\
360    do {\
361        assert(jc->parse_buffer_count >= 1);\
362        --jc->parse_buffer_count;\
363        jc->parse_buffer[jc->parse_buffer_count] = 0;\
364    } while (0)   
365   
366void delete_JSON_parser(JSON_parser jc)
367{
368    if (jc) {
369        if (jc->stack != &jc->static_stack[0]) {
370            free((void*)jc->stack);
371        }
372        if (jc->parse_buffer != &jc->static_parse_buffer[0]) {
373            free((void*)jc->parse_buffer);
374        }
375        free((void*)jc);
376     }   
377}
378
379
380JSON_parser
381new_JSON_parser(JSON_config* config)
382{
383/*
384    new_JSON_parser starts the checking process by constructing a JSON_parser
385    object. It takes a depth parameter that restricts the level of maximum
386    nesting.
387
388    To continue the process, call JSON_parser_char for each character in the
389    JSON text, and then call JSON_parser_done to obtain the final result.
390    These functions are fully reentrant.
391*/
392
393    int depth = 0;
394    JSON_config default_config;
395   
396    JSON_parser jc = malloc(sizeof(struct JSON_parser_struct));
397   
398    memset(jc, 0, sizeof(*jc));
399   
400   
401    /* initialize configuration */
402    init_JSON_config(&default_config);
403   
404    /* set to default configuration if none was provided */
405    if (config == NULL) {
406        config = &default_config;
407    }
408
409    depth = config->depth;
410   
411    /* We need to be able to push at least one object */
412    if (depth == 0) {
413        depth = 1;
414    }
415   
416    jc->state = GO;
417    jc->top = -1;
418   
419    /* Do we want non-bound stack? */
420    if (depth > 0) {
421        jc->stack_capacity = depth;
422        jc->depth = depth;
423        if (depth <= (int)COUNTOF(jc->static_stack)) {
424            jc->stack = &jc->static_stack[0];
425        } else {
426            jc->stack = (signed char*)malloc(jc->stack_capacity * sizeof(jc->static_stack[0]));
427        }
428    } else {
429        jc->stack_capacity = COUNTOF(jc->static_stack);
430        jc->depth = -1;
431        jc->stack = &jc->static_stack[0];
432    }
433   
434    /* set parser to start */
435    push(jc, MODE_DONE);
436   
437    /* set up the parse buffer */
438    jc->parse_buffer = &jc->static_parse_buffer[0];
439    jc->parse_buffer_capacity = COUNTOF(jc->static_parse_buffer);
440    parse_buffer_clear(jc);
441   
442    /* set up callback, comment & float handling */
443    jc->callback = config->callback;
444    jc->ctx = config->callback_ctx;
445    jc->allow_comments = (signed char)config->allow_comments != 0;
446    jc->handle_floats_manually = (signed char)config->handle_floats_manually != 0;
447   
448    /* set up decimal point */
449    jc->decimal_point = *localeconv()->decimal_point;
450   
451    return jc;
452}
453
454static void grow_parse_buffer(JSON_parser jc)
455{
456    assert(jc->parse_buffer_capacity > 0);
457
458    jc->parse_buffer_capacity *= 2;
459    if (jc->parse_buffer == &jc->static_parse_buffer[0]) {
460        jc->parse_buffer = (char*)malloc(jc->parse_buffer_capacity);
461        memcpy(jc->parse_buffer, jc->static_parse_buffer, jc->parse_buffer_count);
462    } else {
463        jc->parse_buffer = (char*)realloc(jc->parse_buffer, jc->parse_buffer_capacity);
464    }
465}
466
467#define parse_buffer_push_back_char(jc, c)\
468    do {\
469        if (jc->parse_buffer_count + 2 >= jc->parse_buffer_capacity) grow_parse_buffer(jc);\
470        jc->parse_buffer[jc->parse_buffer_count++] = c;\
471        jc->parse_buffer[jc->parse_buffer_count]   = 0;\
472    } while (0)
473
474#define assert_is_non_container_type(jc) \
475    assert( \
476        jc->type == JSON_T_NULL || \
477        jc->type == JSON_T_FALSE || \
478        jc->type == JSON_T_TRUE || \
479        jc->type == JSON_T_FLOAT || \
480        jc->type == JSON_T_INTEGER || \
481        jc->type == JSON_T_STRING)
482   
483
484static int parse_parse_buffer(JSON_parser jc)
485{
486    if (jc->callback) {
487        JSON_value value, *arg = NULL;
488       
489        if (jc->type != JSON_T_NONE) {
490            assert_is_non_container_type(jc);
491       
492            switch(jc->type) {
493                case JSON_T_FLOAT:
494                    arg = &value;
495                    if (jc->handle_floats_manually) {
496                        value.vu.str.value = jc->parse_buffer;
497                        value.vu.str.length = jc->parse_buffer_count;
498                    } else { 
499                        /* not checking with end pointer b/c there may be trailing ws */
500                        value.vu.float_value = strtod(jc->parse_buffer, NULL);
501                    }
502                    break;
503                case JSON_T_INTEGER:
504                    arg = &value;
505                    value.vu.integer_value = evutil_strtoll( jc->parse_buffer, NULL, 10 );
506                    break;
507                case JSON_T_STRING:
508                    arg = &value;
509                    value.vu.str.value = jc->parse_buffer;
510                    value.vu.str.length = jc->parse_buffer_count;
511                    break;
512            }
513           
514            if (!(*jc->callback)(jc->ctx, jc->type, arg)) {
515                return false;
516            }
517        }
518    }
519   
520    parse_buffer_clear(jc);
521   
522    return true;
523}
524
525#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
526#define IS_LOW_SURROGATE(uc)  (((uc) & 0xFC00) == 0xDC00)
527#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
528static const unsigned char utf8_lead_bits[4] = { 0x00, 0xC0, 0xE0, 0xF0 };
529
530static int decode_unicode_char(JSON_parser jc)
531{
532    int i;
533    unsigned uc = 0;
534    char* p;
535    int trail_bytes;
536   
537    assert(jc->parse_buffer_count >= 6);
538   
539    p = &jc->parse_buffer[jc->parse_buffer_count - 4];
540   
541    for (i = 12; i >= 0; i -= 4, ++p) {
542        unsigned x = *p;
543       
544        if (x >= 'a') {
545            x -= ('a' - 10);
546        } else if (x >= 'A') {
547            x -= ('A' - 10);
548        } else {
549            x &= ~0x30u;
550        }
551       
552        assert(x < 16);
553       
554        uc |= x << i;
555    }
556   
557    /* clear UTF-16 char from buffer */
558    jc->parse_buffer_count -= 6;
559    jc->parse_buffer[jc->parse_buffer_count] = 0;
560   
561    /* attempt decoding ... */
562    if (jc->utf16_high_surrogate) {
563        if (IS_LOW_SURROGATE(uc)) {
564            uc = DECODE_SURROGATE_PAIR(jc->utf16_high_surrogate, uc);
565            trail_bytes = 3;
566            jc->utf16_high_surrogate = 0;
567        } else {
568            /* high surrogate without a following low surrogate */
569            return false;
570        }
571    } else {
572        if (uc < 0x80) {
573            trail_bytes = 0;
574        } else if (uc < 0x800) {
575            trail_bytes = 1;
576        } else if (IS_HIGH_SURROGATE(uc)) {
577            /* save the high surrogate and wait for the low surrogate */
578            jc->utf16_high_surrogate = (UTF16)uc;
579            return true;
580        } else if (IS_LOW_SURROGATE(uc)) {
581            /* low surrogate without a preceding high surrogate */
582            return false;
583        } else {
584            trail_bytes = 2;
585        }
586    }
587   
588    jc->parse_buffer[jc->parse_buffer_count++] = (char) ((uc >> (trail_bytes * 6)) | utf8_lead_bits[trail_bytes]);
589   
590    for (i = trail_bytes * 6 - 6; i >= 0; i -= 6) {
591        jc->parse_buffer[jc->parse_buffer_count++] = (char) (((uc >> i) & 0x3F) | 0x80);
592    }
593
594    jc->parse_buffer[jc->parse_buffer_count] = 0;
595   
596    return true;
597}
598
599static int add_escaped_char_to_parse_buffer(JSON_parser jc, int next_char)
600{
601    jc->escaped = 0;
602    /* remove the backslash */
603    parse_buffer_pop_back_char(jc);
604    switch(next_char) {
605        case 'b':
606            parse_buffer_push_back_char(jc, '\b');
607            break;
608        case 'f':
609            parse_buffer_push_back_char(jc, '\f');
610            break;
611        case 'n':
612            parse_buffer_push_back_char(jc, '\n');
613            break;
614        case 'r':
615            parse_buffer_push_back_char(jc, '\r');
616            break;
617        case 't':
618            parse_buffer_push_back_char(jc, '\t');
619            break;
620        case '"':
621            parse_buffer_push_back_char(jc, '"');
622            break;
623        case '\\':
624            parse_buffer_push_back_char(jc, '\\');
625            break;
626        case '/':
627            parse_buffer_push_back_char(jc, '/');
628            break;
629        case 'u':
630            parse_buffer_push_back_char(jc, '\\');
631            parse_buffer_push_back_char(jc, 'u');
632            break;
633        default:
634            return false;
635    }
636
637    return true;
638}
639
640#define add_char_to_parse_buffer(jc, next_char, next_class) \
641    do { \
642        if (jc->escaped) { \
643            if (!add_escaped_char_to_parse_buffer(jc, next_char)) \
644                return false; \
645        } else if (!jc->comment) { \
646            if ((jc->type != JSON_T_NONE) | !((next_class == C_SPACE) | (next_class == C_WHITE)) /* non-white-space */) { \
647                parse_buffer_push_back_char(jc, (char)next_char); \
648            } \
649        } \
650    } while (0)
651   
652
653#define assert_type_isnt_string_null_or_bool(jc) \
654    assert(jc->type != JSON_T_FALSE); \
655    assert(jc->type != JSON_T_TRUE); \
656    assert(jc->type != JSON_T_NULL); \
657    assert(jc->type != JSON_T_STRING)
658
659
660int
661JSON_parser_char(JSON_parser jc, int next_char)
662{
663/*
664    After calling new_JSON_parser, call this function for each character (or
665    partial character) in your JSON text. It can accept UTF-8, UTF-16, or
666    UTF-32. It returns true if things are looking ok so far. If it rejects the
667    text, it returns false.
668*/
669    int next_class, next_state;
670   
671/*
672    Determine the character's class.
673*/
674    if (next_char < 0) {
675        return false;
676    }
677    if (next_char >= 128) {
678        next_class = C_ETC;
679    } else {
680        next_class = ascii_class[next_char];
681        if (next_class <= __) {
682            return false;
683        }
684    }
685   
686    add_char_to_parse_buffer(jc, next_char, next_class);
687   
688/*
689    Get the next state from the state transition table.
690*/
691    next_state = state_transition_table[jc->state][next_class];
692    if (next_state >= 0) {
693/*
694    Change the state.
695*/
696        jc->state = (signed char)next_state;
697    } else {
698/*
699    Or perform one of the actions.
700*/
701        switch (next_state) {
702/* Unicode character */       
703        case UC:
704            if(!decode_unicode_char(jc)) {
705                return false;
706            }
707            /* check if we need to read a second UTF-16 char */
708            if (jc->utf16_high_surrogate) {
709                jc->state = D1;
710            } else {
711                jc->state = ST;
712            }
713            break;
714/* escaped char */
715        case EX:
716            jc->escaped = 1;
717            jc->state = ES;
718            break;
719/* integer detected by minus */
720        case MX:
721            jc->type = JSON_T_INTEGER;
722            jc->state = MI;
723            break; 
724/* integer detected by zero */           
725        case ZX:
726            jc->type = JSON_T_INTEGER;
727            jc->state = ZE;
728            break; 
729/* integer detected by 1-9 */           
730        case IX:
731            jc->type = JSON_T_INTEGER;
732            jc->state = IT;
733            break; 
734           
735/* floating point number detected by exponent*/
736        case DE:
737            assert_type_isnt_string_null_or_bool(jc);
738            jc->type = JSON_T_FLOAT;
739            jc->state = E1;
740            break;   
741       
742/* floating point number detected by fraction */
743        case DF:
744            assert_type_isnt_string_null_or_bool(jc);
745            if (!jc->handle_floats_manually) {
746/*
747    Some versions of strtod (which underlies sscanf) don't support converting
748    C-locale formated floating point values.
749*/           
750                assert(jc->parse_buffer[jc->parse_buffer_count-1] == '.');
751                jc->parse_buffer[jc->parse_buffer_count-1] = jc->decimal_point;
752            }           
753            jc->type = JSON_T_FLOAT;
754            jc->state = FX;
755            break;   
756/* string begin " */
757        case SB:
758            parse_buffer_clear(jc);
759            assert(jc->type == JSON_T_NONE);
760            jc->type = JSON_T_STRING;
761            jc->state = ST;
762            break;       
763       
764/* n */
765        case NU:
766            assert(jc->type == JSON_T_NONE);
767            jc->type = JSON_T_NULL;
768            jc->state = N1;
769            break;       
770/* f */
771        case FA:
772            assert(jc->type == JSON_T_NONE);
773            jc->type = JSON_T_FALSE;
774            jc->state = F1;
775            break;       
776/* t */
777        case TR:
778            assert(jc->type == JSON_T_NONE);
779            jc->type = JSON_T_TRUE;
780            jc->state = T1;
781            break;       
782       
783/* closing comment */
784        case CE:
785            jc->comment = 0;
786            assert(jc->parse_buffer_count == 0);
787            assert(jc->type == JSON_T_NONE);
788            jc->state = jc->before_comment_state;
789            break;       
790       
791/* opening comment  */
792        case CB:
793            if (!jc->allow_comments) {
794                return false;
795            }
796            parse_buffer_pop_back_char(jc);
797            if (!parse_parse_buffer(jc)) {
798                return false;
799            }
800            assert(jc->parse_buffer_count == 0);
801            assert(jc->type != JSON_T_STRING);
802            switch (jc->stack[jc->top]) {
803            case MODE_ARRAY:
804            case MODE_OBJECT:   
805                switch(jc->state) {
806                case VA:
807                case AR:
808                    jc->before_comment_state = jc->state;
809                    break;
810                default:
811                    jc->before_comment_state = OK;
812                    break;
813                }
814                break;
815            default:
816                jc->before_comment_state = jc->state;
817                break;
818            }
819            jc->type = JSON_T_NONE;
820            jc->state = C1;
821            jc->comment = 1;
822            break;
823/* empty } */
824        case -9:       
825            parse_buffer_clear(jc);
826            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
827                return false;
828            }
829            if (!pop(jc, MODE_KEY)) {
830                return false;
831            }
832            jc->state = OK;
833            break;
834
835/* } */ case -8:
836            parse_buffer_pop_back_char(jc);
837            if (!parse_parse_buffer(jc)) {
838                return false;
839            }
840            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) {
841                return false;
842            }
843            if (!pop(jc, MODE_OBJECT)) {
844                return false;
845            }
846            jc->type = JSON_T_NONE;
847            jc->state = OK;
848            break;
849
850/* ] */ case -7:
851            parse_buffer_pop_back_char(jc);
852            if (!parse_parse_buffer(jc)) {
853                return false;
854            }
855            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_END, NULL)) {
856                return false;
857            }
858            if (!pop(jc, MODE_ARRAY)) {
859                return false;
860            }
861           
862            jc->type = JSON_T_NONE;
863            jc->state = OK;
864            break;
865
866/* { */ case -6:
867            parse_buffer_pop_back_char(jc);
868            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_BEGIN, NULL)) {
869                return false;
870            }
871            if (!push(jc, MODE_KEY)) {
872                return false;
873            }
874            assert(jc->type == JSON_T_NONE);
875            jc->state = OB;
876            break;
877
878/* [ */ case -5:
879            parse_buffer_pop_back_char(jc);
880            if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_BEGIN, NULL)) {
881                return false;
882            }
883            if (!push(jc, MODE_ARRAY)) {
884                return false;
885            }
886            assert(jc->type == JSON_T_NONE);
887            jc->state = AR;
888            break;
889
890/* string end " */ case -4:
891            parse_buffer_pop_back_char(jc);
892            switch (jc->stack[jc->top]) {
893            case MODE_KEY:
894                assert(jc->type == JSON_T_STRING);
895                jc->type = JSON_T_NONE;
896                jc->state = CO;
897               
898                if (jc->callback) {
899                    JSON_value value;
900                    value.vu.str.value = jc->parse_buffer;
901                    value.vu.str.length = jc->parse_buffer_count;
902                    if (!(*jc->callback)(jc->ctx, JSON_T_KEY, &value)) {
903                        return false;
904                    }
905                }
906                parse_buffer_clear(jc);
907                break;
908            case MODE_ARRAY:
909            case MODE_OBJECT:
910                assert(jc->type == JSON_T_STRING);
911                if (!parse_parse_buffer(jc)) {
912                    return false;
913                }
914                jc->type = JSON_T_NONE;
915                jc->state = OK;
916                break;
917            default:
918                return false;
919            }
920            break;
921
922/* , */ case -3:
923            parse_buffer_pop_back_char(jc);
924            if (!parse_parse_buffer(jc)) {
925                return false;
926            }
927            switch (jc->stack[jc->top]) {
928            case MODE_OBJECT:
929/*
930    A comma causes a flip from object mode to key mode.
931*/
932                if (!pop(jc, MODE_OBJECT) || !push(jc, MODE_KEY)) {
933                    return false;
934                }
935                assert(jc->type != JSON_T_STRING);
936                jc->type = JSON_T_NONE;
937                jc->state = KE;
938                break;
939            case MODE_ARRAY:
940                assert(jc->type != JSON_T_STRING);
941                jc->type = JSON_T_NONE;
942                jc->state = VA;
943                break;
944            default:
945                return false;
946            }
947            break;
948
949/* : */ case -2:
950/*
951    A colon causes a flip from key mode to object mode.
952*/
953            parse_buffer_pop_back_char(jc);
954            if (!pop(jc, MODE_KEY) || !push(jc, MODE_OBJECT)) {
955                return false;
956            }
957            assert(jc->type == JSON_T_NONE);
958            jc->state = VA;
959            break;
960/*
961    Bad action.
962*/
963        default:
964            return false;
965        }
966    }
967    return true;
968}
969
970
971int
972JSON_parser_done(JSON_parser jc)
973{
974    const int result = jc->state == OK && pop(jc, MODE_DONE);
975
976    return result;
977}
978
979
980int JSON_parser_is_legal_white_space_string(const char* s)
981{
982    int c, char_class;
983   
984    if (s == NULL) {
985        return false;
986    }
987   
988    for (; *s; ++s) {   
989        c = *s;
990       
991        if (c < 0 || c >= 128) {
992            return false;
993        }
994       
995        char_class = ascii_class[c];
996       
997        if (char_class != C_SPACE && char_class != C_WHITE) {
998            return false;
999        }
1000    }
1001   
1002    return true;
1003}
1004
1005
1006void init_JSON_config(JSON_config* config)
1007{
1008    if (config) {
1009        memset(config, 0, sizeof(*config));
1010       
1011        config->depth = JSON_PARSER_STACK_SIZE - 1;
1012    }
1013}
Note: See TracBrowser for help on using the repository browser.