source: trunk/libtransmission/JSON_parser.c @ 11588

Last change on this file since 11588 was 11588, checked in by charles, 11 years ago

(trunk libT) #3836 "libevent2 support" -- finish moving to the libevent2 API mode. don't include the backwards-compatable API headers.

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