json 1.2.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of json might be problematic. Click here for more details.

@@ -0,0 +1,170 @@
1
+ #ifndef _GENERATOR_H_
2
+ #define _GENERATOR_H_
3
+
4
+ #include <string.h>
5
+ #include <assert.h>
6
+ #include <math.h>
7
+
8
+ #include "ruby.h"
9
+
10
+ #if HAVE_RUBY_RE_H
11
+ #include "ruby/re.h"
12
+ #endif
13
+
14
+ #if HAVE_RE_H
15
+ #include "re.h"
16
+ #endif
17
+
18
+ #ifdef HAVE_RUBY_ENCODING_H
19
+ #include "ruby/encoding.h"
20
+ #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
21
+ #else
22
+ #define FORCE_UTF8(obj)
23
+ #endif
24
+
25
+ #define option_given_p(opts, key) RTEST(rb_funcall(opts, i_key_p, 1, key))
26
+
27
+ #ifndef RHASH_SIZE
28
+ #define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
29
+ #endif
30
+
31
+ #ifndef RFLOAT_VALUE
32
+ #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
33
+ #endif
34
+
35
+ #ifndef RARRAY_PTR
36
+ #define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr
37
+ #endif
38
+ #ifndef RARRAY_LEN
39
+ #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
40
+ #endif
41
+ #ifndef RSTRING_PTR
42
+ #define RSTRING_PTR(string) RSTRING(string)->ptr
43
+ #endif
44
+ #ifndef RSTRING_LEN
45
+ #define RSTRING_LEN(string) RSTRING(string)->len
46
+ #endif
47
+
48
+ #define RSTRING_PAIR(string) RSTRING_PTR(string), RSTRING_LEN(string)
49
+
50
+ /* fbuffer implementation */
51
+
52
+ typedef struct FBufferStruct {
53
+ unsigned int initial_length;
54
+ char *ptr;
55
+ unsigned int len;
56
+ unsigned int capa;
57
+ } FBuffer;
58
+
59
+ #define FBUFFER_INITIAL_LENGTH 4096
60
+
61
+ #define FBUFFER_PTR(fb) (fb->ptr)
62
+ #define FBUFFER_LEN(fb) (fb->len)
63
+ #define FBUFFER_CAPA(fb) (fb->capa)
64
+ #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
65
+
66
+ static char *fstrndup(const char *ptr, int len);
67
+ static FBuffer *fbuffer_alloc();
68
+ static FBuffer *fbuffer_alloc_with_length(unsigned initial_length);
69
+ static void fbuffer_free(FBuffer *fb);
70
+ static void fbuffer_free_only_buffer(FBuffer *fb);
71
+ static void fbuffer_clear(FBuffer *fb);
72
+ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len);
73
+ static void fbuffer_append_integer(FBuffer *fb, int number);
74
+ static void fbuffer_append_char(FBuffer *fb, char newchr);
75
+ static FBuffer *fbuffer_dup(FBuffer *fb);
76
+
77
+ /* unicode defintions */
78
+
79
+ #define UNI_STRICT_CONVERSION 1
80
+
81
+ typedef unsigned long UTF32; /* at least 32 bits */
82
+ typedef unsigned short UTF16; /* at least 16 bits */
83
+ typedef unsigned char UTF8; /* typically 8 bits */
84
+
85
+ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
86
+ #define UNI_MAX_BMP (UTF32)0x0000FFFF
87
+ #define UNI_MAX_UTF16 (UTF32)0x0010FFFF
88
+ #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
89
+ #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
90
+
91
+ #define UNI_SUR_HIGH_START (UTF32)0xD800
92
+ #define UNI_SUR_HIGH_END (UTF32)0xDBFF
93
+ #define UNI_SUR_LOW_START (UTF32)0xDC00
94
+ #define UNI_SUR_LOW_END (UTF32)0xDFFF
95
+
96
+ static const int halfShift = 10; /* used for shifting by 10 bits */
97
+
98
+ static const UTF32 halfBase = 0x0010000UL;
99
+ static const UTF32 halfMask = 0x3FFUL;
100
+
101
+ static unsigned char isLegalUTF8(const UTF8 *source, int length);
102
+ static void unicode_escape(char *buf, UTF16 character);
103
+ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
104
+ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
105
+ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
106
+
107
+ /* ruby api and some helpers */
108
+
109
+ typedef struct JSON_Generator_StateStruct {
110
+ char *indent;
111
+ long indent_len;
112
+ char *space;
113
+ long space_len;
114
+ char *space_before;
115
+ long space_before_len;
116
+ char *object_nl;
117
+ long object_nl_len;
118
+ char *array_nl;
119
+ long array_nl_len;
120
+ FBuffer *array_delim;
121
+ FBuffer *object_delim;
122
+ FBuffer *object_delim2;
123
+ long max_nesting;
124
+ char allow_nan;
125
+ char ascii_only;
126
+ } JSON_Generator_State;
127
+
128
+ #define GET_STATE(self) \
129
+ JSON_Generator_State *state; \
130
+ Data_Get_Struct(self, JSON_Generator_State, state)
131
+
132
+ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
133
+ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self);
134
+ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self);
135
+ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self);
136
+ static VALUE mString_included_s(VALUE self, VALUE modul);
137
+ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self);
138
+ static VALUE mString_to_json_raw_object(VALUE self);
139
+ static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self);
140
+ static VALUE mString_Extend_json_create(VALUE self, VALUE o);
141
+ static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self);
142
+ static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self);
143
+ static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self);
144
+ static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self);
145
+ static void State_free(JSON_Generator_State *state);
146
+ static JSON_Generator_State *State_allocate();
147
+ static VALUE cState_s_allocate(VALUE klass);
148
+ static VALUE cState_configure(VALUE self, VALUE opts);
149
+ static VALUE cState_to_h(VALUE self);
150
+ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj, long depth);
151
+ static VALUE cState_partial_generate(VALUE self, VALUE obj, VALUE depth);
152
+ static VALUE cState_generate(VALUE self, VALUE obj);
153
+ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self);
154
+ static VALUE cState_from_state_s(VALUE self, VALUE opts);
155
+ static VALUE cState_indent(VALUE self);
156
+ static VALUE cState_indent_set(VALUE self, VALUE indent);
157
+ static VALUE cState_space(VALUE self);
158
+ static VALUE cState_space_set(VALUE self, VALUE space);
159
+ static VALUE cState_space_before(VALUE self);
160
+ static VALUE cState_space_before_set(VALUE self, VALUE space_before);
161
+ static VALUE cState_object_nl(VALUE self);
162
+ static VALUE cState_object_nl_set(VALUE self, VALUE object_nl);
163
+ static VALUE cState_array_nl(VALUE self);
164
+ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl);
165
+ static VALUE cState_max_nesting(VALUE self);
166
+ static VALUE cState_max_nesting_set(VALUE self, VALUE depth);
167
+ static VALUE cState_allow_nan_p(VALUE self);
168
+ static VALUE cState_ascii_only_p(VALUE self);
169
+
170
+ #endif
@@ -1,23 +1,76 @@
1
1
 
2
2
  #line 1 "parser.rl"
3
- #include "ruby.h"
4
- #include "unicode.h"
5
- #if HAVE_RE_H
6
- #include "re.h"
7
- #endif
8
-
9
- #define EVIL 0x666
3
+ #include "parser.h"
4
+
5
+ /* unicode */
6
+
7
+ static const char digit_values[256] = {
8
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
11
+ -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
12
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
13
+ 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
14
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
16
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
17
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
21
+ -1, -1, -1, -1, -1, -1, -1
22
+ };
23
+
24
+ static UTF32 unescape_unicode(const unsigned char *p)
25
+ {
26
+ char b;
27
+ UTF32 result = 0;
28
+ b = digit_values[p[0]];
29
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
30
+ result = (result << 4) | b;
31
+ b = digit_values[p[1]];
32
+ result = (result << 4) | b;
33
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
34
+ b = digit_values[p[2]];
35
+ result = (result << 4) | b;
36
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
37
+ b = digit_values[p[3]];
38
+ result = (result << 4) | b;
39
+ if (b < 0) return UNI_REPLACEMENT_CHAR;
40
+ return result;
41
+ }
10
42
 
11
- #define option_given_p(opts, key) RTEST(rb_funcall((opts), i_key_p, 1, (key)))
43
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
44
+ {
45
+ int len = 1;
46
+ if (ch <= 0x7F) {
47
+ buf[0] = (char) ch;
48
+ } else if (ch <= 0x07FF) {
49
+ buf[0] = (char) ((ch >> 6) | 0xC0);
50
+ buf[1] = (char) ((ch & 0x3F) | 0x80);
51
+ len++;
52
+ } else if (ch <= 0xFFFF) {
53
+ buf[0] = (char) ((ch >> 12) | 0xE0);
54
+ buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
55
+ buf[2] = (char) ((ch & 0x3F) | 0x80);
56
+ len += 2;
57
+ } else if (ch <= 0x1fffff) {
58
+ buf[0] =(char) ((ch >> 18) | 0xF0);
59
+ buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
60
+ buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
61
+ buf[3] =(char) ((ch & 0x3F) | 0x80);
62
+ len += 3;
63
+ } else {
64
+ buf[0] = '?';
65
+ }
66
+ return len;
67
+ }
12
68
 
13
69
  #ifdef HAVE_RUBY_ENCODING_H
14
- #include "ruby/encoding.h"
15
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
16
- static VALUE mEncoding_ASCII_8BIT, mEncoding_UTF_8, mEncoding_UTF_16BE,
17
- mEncoding_UTF_16LE, mEncoding_UTF_32BE, mEncoding_UTF_32LE;
70
+ static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
71
+ CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
18
72
  static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
19
73
  #else
20
- #define FORCE_UTF8(obj)
21
74
  static ID i_iconv;
22
75
  #endif
23
76
 
@@ -28,40 +81,12 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
28
81
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
29
82
  i_array_class, i_key_p, i_deep_const_get;
30
83
 
31
- #define MinusInfinity "-Infinity"
32
-
33
- typedef struct JSON_ParserStruct {
34
- VALUE Vsource;
35
- char *source;
36
- long len;
37
- char *memo;
38
- VALUE create_id;
39
- int max_nesting;
40
- int current_nesting;
41
- int allow_nan;
42
- int parsing_name;
43
- int symbolize_names;
44
- VALUE object_class;
45
- VALUE array_class;
46
- } JSON_Parser;
47
-
48
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
49
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
50
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
51
- static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
52
- static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
53
- static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
54
-
55
- #define GET_STRUCT \
56
- JSON_Parser *json; \
57
- Data_Get_Struct(self, JSON_Parser, json);
58
84
 
85
+ #line 108 "parser.rl"
59
86
 
60
- #line 83 "parser.rl"
61
87
 
62
88
 
63
-
64
- #line 65 "parser.c"
89
+ #line 90 "parser.c"
65
90
  static const int JSON_object_start = 1;
66
91
  static const int JSON_object_first_final = 27;
67
92
  static const int JSON_object_error = 0;
@@ -69,7 +94,7 @@ static const int JSON_object_error = 0;
69
94
  static const int JSON_object_en_main = 1;
70
95
 
71
96
 
72
- #line 118 "parser.rl"
97
+ #line 143 "parser.rl"
73
98
 
74
99
 
75
100
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -85,14 +110,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
85
110
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
86
111
 
87
112
 
88
- #line 89 "parser.c"
113
+ #line 114 "parser.c"
89
114
  {
90
115
  cs = JSON_object_start;
91
116
  }
92
117
 
93
- #line 133 "parser.rl"
118
+ #line 158 "parser.rl"
94
119
 
95
- #line 96 "parser.c"
120
+ #line 121 "parser.c"
96
121
  {
97
122
  if ( p == pe )
98
123
  goto _test_eof;
@@ -120,7 +145,7 @@ case 2:
120
145
  goto st2;
121
146
  goto st0;
122
147
  tr2:
123
- #line 102 "parser.rl"
148
+ #line 127 "parser.rl"
124
149
  {
125
150
  json->parsing_name = 1;
126
151
  char *np = JSON_parse_string(json, p, pe, &last_name);
@@ -132,7 +157,7 @@ st3:
132
157
  if ( ++p == pe )
133
158
  goto _test_eof3;
134
159
  case 3:
135
- #line 136 "parser.c"
160
+ #line 161 "parser.c"
136
161
  switch( (*p) ) {
137
162
  case 13: goto st3;
138
163
  case 32: goto st3;
@@ -199,7 +224,7 @@ case 8:
199
224
  goto st8;
200
225
  goto st0;
201
226
  tr11:
202
- #line 91 "parser.rl"
227
+ #line 116 "parser.rl"
203
228
  {
204
229
  VALUE v = Qnil;
205
230
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -215,7 +240,7 @@ st9:
215
240
  if ( ++p == pe )
216
241
  goto _test_eof9;
217
242
  case 9:
218
- #line 219 "parser.c"
243
+ #line 244 "parser.c"
219
244
  switch( (*p) ) {
220
245
  case 13: goto st9;
221
246
  case 32: goto st9;
@@ -304,14 +329,14 @@ case 18:
304
329
  goto st9;
305
330
  goto st18;
306
331
  tr4:
307
- #line 109 "parser.rl"
332
+ #line 134 "parser.rl"
308
333
  { p--; {p++; cs = 27; goto _out;} }
309
334
  goto st27;
310
335
  st27:
311
336
  if ( ++p == pe )
312
337
  goto _test_eof27;
313
338
  case 27:
314
- #line 315 "parser.c"
339
+ #line 340 "parser.c"
315
340
  goto st0;
316
341
  st19:
317
342
  if ( ++p == pe )
@@ -409,7 +434,7 @@ case 26:
409
434
  _out: {}
410
435
  }
411
436
 
412
- #line 134 "parser.rl"
437
+ #line 159 "parser.rl"
413
438
 
414
439
  if (cs >= JSON_object_first_final) {
415
440
  if (RTEST(json->create_id)) {
@@ -428,7 +453,7 @@ case 26:
428
453
  }
429
454
 
430
455
 
431
- #line 432 "parser.c"
456
+ #line 457 "parser.c"
432
457
  static const int JSON_value_start = 1;
433
458
  static const int JSON_value_first_final = 21;
434
459
  static const int JSON_value_error = 0;
@@ -436,7 +461,7 @@ static const int JSON_value_error = 0;
436
461
  static const int JSON_value_en_main = 1;
437
462
 
438
463
 
439
- #line 232 "parser.rl"
464
+ #line 257 "parser.rl"
440
465
 
441
466
 
442
467
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -444,14 +469,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
444
469
  int cs = EVIL;
445
470
 
446
471
 
447
- #line 448 "parser.c"
472
+ #line 473 "parser.c"
448
473
  {
449
474
  cs = JSON_value_start;
450
475
  }
451
476
 
452
- #line 239 "parser.rl"
477
+ #line 264 "parser.rl"
453
478
 
454
- #line 455 "parser.c"
479
+ #line 480 "parser.c"
455
480
  {
456
481
  if ( p == pe )
457
482
  goto _test_eof;
@@ -476,14 +501,14 @@ st0:
476
501
  cs = 0;
477
502
  goto _out;
478
503
  tr0:
479
- #line 180 "parser.rl"
504
+ #line 205 "parser.rl"
480
505
  {
481
506
  char *np = JSON_parse_string(json, p, pe, result);
482
507
  if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
483
508
  }
484
509
  goto st21;
485
510
  tr2:
486
- #line 185 "parser.rl"
511
+ #line 210 "parser.rl"
487
512
  {
488
513
  char *np;
489
514
  if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
@@ -503,7 +528,7 @@ tr2:
503
528
  }
504
529
  goto st21;
505
530
  tr5:
506
- #line 203 "parser.rl"
531
+ #line 228 "parser.rl"
507
532
  {
508
533
  char *np;
509
534
  json->current_nesting++;
@@ -513,7 +538,7 @@ tr5:
513
538
  }
514
539
  goto st21;
515
540
  tr9:
516
- #line 211 "parser.rl"
541
+ #line 236 "parser.rl"
517
542
  {
518
543
  char *np;
519
544
  json->current_nesting++;
@@ -523,7 +548,7 @@ tr9:
523
548
  }
524
549
  goto st21;
525
550
  tr16:
526
- #line 173 "parser.rl"
551
+ #line 198 "parser.rl"
527
552
  {
528
553
  if (json->allow_nan) {
529
554
  *result = CInfinity;
@@ -533,7 +558,7 @@ tr16:
533
558
  }
534
559
  goto st21;
535
560
  tr18:
536
- #line 166 "parser.rl"
561
+ #line 191 "parser.rl"
537
562
  {
538
563
  if (json->allow_nan) {
539
564
  *result = CNaN;
@@ -543,19 +568,19 @@ tr18:
543
568
  }
544
569
  goto st21;
545
570
  tr22:
546
- #line 160 "parser.rl"
571
+ #line 185 "parser.rl"
547
572
  {
548
573
  *result = Qfalse;
549
574
  }
550
575
  goto st21;
551
576
  tr25:
552
- #line 157 "parser.rl"
577
+ #line 182 "parser.rl"
553
578
  {
554
579
  *result = Qnil;
555
580
  }
556
581
  goto st21;
557
582
  tr28:
558
- #line 163 "parser.rl"
583
+ #line 188 "parser.rl"
559
584
  {
560
585
  *result = Qtrue;
561
586
  }
@@ -564,9 +589,9 @@ st21:
564
589
  if ( ++p == pe )
565
590
  goto _test_eof21;
566
591
  case 21:
567
- #line 219 "parser.rl"
592
+ #line 244 "parser.rl"
568
593
  { p--; {p++; cs = 21; goto _out;} }
569
- #line 570 "parser.c"
594
+ #line 595 "parser.c"
570
595
  goto st0;
571
596
  st2:
572
597
  if ( ++p == pe )
@@ -727,7 +752,7 @@ case 20:
727
752
  _out: {}
728
753
  }
729
754
 
730
- #line 240 "parser.rl"
755
+ #line 265 "parser.rl"
731
756
 
732
757
  if (cs >= JSON_value_first_final) {
733
758
  return p;
@@ -737,7 +762,7 @@ case 20:
737
762
  }
738
763
 
739
764
 
740
- #line 741 "parser.c"
765
+ #line 766 "parser.c"
741
766
  static const int JSON_integer_start = 1;
742
767
  static const int JSON_integer_first_final = 5;
743
768
  static const int JSON_integer_error = 0;
@@ -745,7 +770,7 @@ static const int JSON_integer_error = 0;
745
770
  static const int JSON_integer_en_main = 1;
746
771
 
747
772
 
748
- #line 256 "parser.rl"
773
+ #line 281 "parser.rl"
749
774
 
750
775
 
751
776
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -753,15 +778,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
753
778
  int cs = EVIL;
754
779
 
755
780
 
756
- #line 757 "parser.c"
781
+ #line 782 "parser.c"
757
782
  {
758
783
  cs = JSON_integer_start;
759
784
  }
760
785
 
761
- #line 263 "parser.rl"
786
+ #line 288 "parser.rl"
762
787
  json->memo = p;
763
788
 
764
- #line 765 "parser.c"
789
+ #line 790 "parser.c"
765
790
  {
766
791
  if ( p == pe )
767
792
  goto _test_eof;
@@ -795,14 +820,14 @@ case 3:
795
820
  goto st0;
796
821
  goto tr4;
797
822
  tr4:
798
- #line 253 "parser.rl"
823
+ #line 278 "parser.rl"
799
824
  { p--; {p++; cs = 5; goto _out;} }
800
825
  goto st5;
801
826
  st5:
802
827
  if ( ++p == pe )
803
828
  goto _test_eof5;
804
829
  case 5:
805
- #line 806 "parser.c"
830
+ #line 831 "parser.c"
806
831
  goto st0;
807
832
  st4:
808
833
  if ( ++p == pe )
@@ -821,7 +846,7 @@ case 4:
821
846
  _out: {}
822
847
  }
823
848
 
824
- #line 265 "parser.rl"
849
+ #line 290 "parser.rl"
825
850
 
826
851
  if (cs >= JSON_integer_first_final) {
827
852
  long len = p - json->memo;
@@ -833,7 +858,7 @@ case 4:
833
858
  }
834
859
 
835
860
 
836
- #line 837 "parser.c"
861
+ #line 862 "parser.c"
837
862
  static const int JSON_float_start = 1;
838
863
  static const int JSON_float_first_final = 10;
839
864
  static const int JSON_float_error = 0;
@@ -841,7 +866,7 @@ static const int JSON_float_error = 0;
841
866
  static const int JSON_float_en_main = 1;
842
867
 
843
868
 
844
- #line 287 "parser.rl"
869
+ #line 312 "parser.rl"
845
870
 
846
871
 
847
872
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -849,15 +874,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
849
874
  int cs = EVIL;
850
875
 
851
876
 
852
- #line 853 "parser.c"
877
+ #line 878 "parser.c"
853
878
  {
854
879
  cs = JSON_float_start;
855
880
  }
856
881
 
857
- #line 294 "parser.rl"
882
+ #line 319 "parser.rl"
858
883
  json->memo = p;
859
884
 
860
- #line 861 "parser.c"
885
+ #line 886 "parser.c"
861
886
  {
862
887
  if ( p == pe )
863
888
  goto _test_eof;
@@ -915,14 +940,14 @@ case 5:
915
940
  goto st0;
916
941
  goto tr7;
917
942
  tr7:
918
- #line 281 "parser.rl"
943
+ #line 306 "parser.rl"
919
944
  { p--; {p++; cs = 10; goto _out;} }
920
945
  goto st10;
921
946
  st10:
922
947
  if ( ++p == pe )
923
948
  goto _test_eof10;
924
949
  case 10:
925
- #line 926 "parser.c"
950
+ #line 951 "parser.c"
926
951
  goto st0;
927
952
  st6:
928
953
  if ( ++p == pe )
@@ -983,7 +1008,7 @@ case 9:
983
1008
  _out: {}
984
1009
  }
985
1010
 
986
- #line 296 "parser.rl"
1011
+ #line 321 "parser.rl"
987
1012
 
988
1013
  if (cs >= JSON_float_first_final) {
989
1014
  long len = p - json->memo;
@@ -996,7 +1021,7 @@ case 9:
996
1021
 
997
1022
 
998
1023
 
999
- #line 1000 "parser.c"
1024
+ #line 1025 "parser.c"
1000
1025
  static const int JSON_array_start = 1;
1001
1026
  static const int JSON_array_first_final = 17;
1002
1027
  static const int JSON_array_error = 0;
@@ -1004,7 +1029,7 @@ static const int JSON_array_error = 0;
1004
1029
  static const int JSON_array_en_main = 1;
1005
1030
 
1006
1031
 
1007
- #line 332 "parser.rl"
1032
+ #line 357 "parser.rl"
1008
1033
 
1009
1034
 
1010
1035
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -1018,14 +1043,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
1018
1043
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1019
1044
 
1020
1045
 
1021
- #line 1022 "parser.c"
1046
+ #line 1047 "parser.c"
1022
1047
  {
1023
1048
  cs = JSON_array_start;
1024
1049
  }
1025
1050
 
1026
- #line 345 "parser.rl"
1051
+ #line 370 "parser.rl"
1027
1052
 
1028
- #line 1029 "parser.c"
1053
+ #line 1054 "parser.c"
1029
1054
  {
1030
1055
  if ( p == pe )
1031
1056
  goto _test_eof;
@@ -1064,7 +1089,7 @@ case 2:
1064
1089
  goto st2;
1065
1090
  goto st0;
1066
1091
  tr2:
1067
- #line 313 "parser.rl"
1092
+ #line 338 "parser.rl"
1068
1093
  {
1069
1094
  VALUE v = Qnil;
1070
1095
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -1080,7 +1105,7 @@ st3:
1080
1105
  if ( ++p == pe )
1081
1106
  goto _test_eof3;
1082
1107
  case 3:
1083
- #line 1084 "parser.c"
1108
+ #line 1109 "parser.c"
1084
1109
  switch( (*p) ) {
1085
1110
  case 13: goto st3;
1086
1111
  case 32: goto st3;
@@ -1180,14 +1205,14 @@ case 12:
1180
1205
  goto st3;
1181
1206
  goto st12;
1182
1207
  tr4:
1183
- #line 324 "parser.rl"
1208
+ #line 349 "parser.rl"
1184
1209
  { p--; {p++; cs = 17; goto _out;} }
1185
1210
  goto st17;
1186
1211
  st17:
1187
1212
  if ( ++p == pe )
1188
1213
  goto _test_eof17;
1189
1214
  case 17:
1190
- #line 1191 "parser.c"
1215
+ #line 1216 "parser.c"
1191
1216
  goto st0;
1192
1217
  st13:
1193
1218
  if ( ++p == pe )
@@ -1243,73 +1268,88 @@ case 16:
1243
1268
  _out: {}
1244
1269
  }
1245
1270
 
1246
- #line 346 "parser.rl"
1271
+ #line 371 "parser.rl"
1247
1272
 
1248
1273
  if(cs >= JSON_array_first_final) {
1249
1274
  return p + 1;
1250
1275
  } else {
1251
1276
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1277
+ return NULL;
1252
1278
  }
1253
1279
  }
1254
1280
 
1255
- static VALUE json_string_unescape(char *p, char *pe)
1281
+ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1256
1282
  {
1257
- VALUE result = rb_str_buf_new(pe - p + 1);
1258
-
1259
- while (p < pe) {
1260
- if (*p == '\\') {
1261
- p++;
1262
- if (p >= pe) return Qnil; /* raise an exception later, \ at end */
1263
- switch (*p) {
1283
+ char *p = string, *pe = string, *unescape;
1284
+ int unescape_len;
1285
+
1286
+ while (pe < stringEnd) {
1287
+ if (*pe == '\\') {
1288
+ unescape = (char *) "?";
1289
+ unescape_len = 1;
1290
+ if (pe > p) rb_str_buf_cat(result, p, pe - p);
1291
+ switch (*++pe) {
1292
+ case 'n':
1293
+ unescape = (char *) "\n";
1294
+ break;
1295
+ case 'r':
1296
+ unescape = (char *) "\r";
1297
+ break;
1298
+ case 't':
1299
+ unescape = (char *) "\t";
1300
+ break;
1264
1301
  case '"':
1302
+ unescape = (char *) "\"";
1303
+ break;
1265
1304
  case '\\':
1266
- rb_str_buf_cat(result, p, 1);
1267
- p++;
1305
+ unescape = (char *) "\\";
1268
1306
  break;
1269
1307
  case 'b':
1270
- rb_str_buf_cat2(result, "\b");
1271
- p++;
1308
+ unescape = (char *) "\b";
1272
1309
  break;
1273
1310
  case 'f':
1274
- rb_str_buf_cat2(result, "\f");
1275
- p++;
1276
- break;
1277
- case 'n':
1278
- rb_str_buf_cat2(result, "\n");
1279
- p++;
1280
- break;
1281
- case 'r':
1282
- rb_str_buf_cat2(result, "\r");
1283
- p++;
1284
- break;
1285
- case 't':
1286
- rb_str_buf_cat2(result, "\t");
1287
- p++;
1311
+ unescape = (char *) "\f";
1288
1312
  break;
1289
1313
  case 'u':
1290
- if (p > pe - 4) {
1314
+ if (pe > stringEnd - 4) {
1291
1315
  return Qnil;
1292
1316
  } else {
1293
- p = JSON_convert_UTF16_to_UTF8(result, p, pe, strictConversion);
1317
+ char buf[4];
1318
+ UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1319
+ pe += 3;
1320
+ if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1321
+ pe++;
1322
+ if (pe > stringEnd - 6) return Qnil;
1323
+ if (pe[0] == '\\' && pe[1] == 'u') {
1324
+ UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1325
+ ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1326
+ | (sur & 0x3FF));
1327
+ pe += 5;
1328
+ } else {
1329
+ unescape = (char *) "?";
1330
+ break;
1331
+ }
1332
+ }
1333
+ unescape_len = convert_UTF32_to_UTF8(buf, ch);
1334
+ unescape = buf;
1294
1335
  }
1295
1336
  break;
1296
1337
  default:
1297
- rb_str_buf_cat(result, p, 1);
1298
- p++;
1299
- break;
1338
+ p = pe;
1339
+ continue;
1300
1340
  }
1341
+ rb_str_buf_cat(result, unescape, unescape_len);
1342
+ p = ++pe;
1301
1343
  } else {
1302
- char *q = p;
1303
- while (*q != '\\' && q < pe) q++;
1304
- rb_str_buf_cat(result, p, q - p);
1305
- p = q;
1344
+ pe++;
1306
1345
  }
1307
1346
  }
1347
+ rb_str_buf_cat(result, p, pe - p);
1308
1348
  return result;
1309
1349
  }
1310
1350
 
1311
1351
 
1312
- #line 1313 "parser.c"
1352
+ #line 1353 "parser.c"
1313
1353
  static const int JSON_string_start = 1;
1314
1354
  static const int JSON_string_first_final = 8;
1315
1355
  static const int JSON_string_error = 0;
@@ -1317,24 +1357,24 @@ static const int JSON_string_error = 0;
1317
1357
  static const int JSON_string_en_main = 1;
1318
1358
 
1319
1359
 
1320
- #line 430 "parser.rl"
1360
+ #line 470 "parser.rl"
1321
1361
 
1322
1362
 
1323
1363
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1324
1364
  {
1325
1365
  int cs = EVIL;
1326
1366
 
1327
- *result = rb_str_new("", 0);
1367
+ *result = rb_str_buf_new(0);
1328
1368
 
1329
- #line 1330 "parser.c"
1369
+ #line 1370 "parser.c"
1330
1370
  {
1331
1371
  cs = JSON_string_start;
1332
1372
  }
1333
1373
 
1334
- #line 438 "parser.rl"
1374
+ #line 478 "parser.rl"
1335
1375
  json->memo = p;
1336
1376
 
1337
- #line 1338 "parser.c"
1377
+ #line 1378 "parser.c"
1338
1378
  {
1339
1379
  if ( p == pe )
1340
1380
  goto _test_eof;
@@ -1359,25 +1399,25 @@ case 2:
1359
1399
  goto st0;
1360
1400
  goto st2;
1361
1401
  tr2:
1362
- #line 416 "parser.rl"
1402
+ #line 456 "parser.rl"
1363
1403
  {
1364
- *result = json_string_unescape(json->memo + 1, p);
1365
- if (NIL_P(*result)) {
1366
- p--;
1367
- {p++; cs = 8; goto _out;}
1368
- } else {
1369
- FORCE_UTF8(*result);
1370
- {p = (( p + 1))-1;}
1371
- }
1372
- }
1373
- #line 427 "parser.rl"
1404
+ *result = json_string_unescape(*result, json->memo + 1, p);
1405
+ if (NIL_P(*result)) {
1406
+ p--;
1407
+ {p++; cs = 8; goto _out;}
1408
+ } else {
1409
+ FORCE_UTF8(*result);
1410
+ {p = (( p + 1))-1;}
1411
+ }
1412
+ }
1413
+ #line 467 "parser.rl"
1374
1414
  { p--; {p++; cs = 8; goto _out;} }
1375
1415
  goto st8;
1376
1416
  st8:
1377
1417
  if ( ++p == pe )
1378
1418
  goto _test_eof8;
1379
1419
  case 8:
1380
- #line 1381 "parser.c"
1420
+ #line 1421 "parser.c"
1381
1421
  goto st0;
1382
1422
  st3:
1383
1423
  if ( ++p == pe )
@@ -1453,7 +1493,7 @@ case 7:
1453
1493
  _out: {}
1454
1494
  }
1455
1495
 
1456
- #line 440 "parser.rl"
1496
+ #line 480 "parser.rl"
1457
1497
 
1458
1498
  if (json->symbolize_names && json->parsing_name) {
1459
1499
  *result = rb_str_intern(*result);
@@ -1467,7 +1507,7 @@ case 7:
1467
1507
 
1468
1508
 
1469
1509
 
1470
- #line 1471 "parser.c"
1510
+ #line 1511 "parser.c"
1471
1511
  static const int JSON_start = 1;
1472
1512
  static const int JSON_first_final = 10;
1473
1513
  static const int JSON_error = 0;
@@ -1475,7 +1515,7 @@ static const int JSON_error = 0;
1475
1515
  static const int JSON_en_main = 1;
1476
1516
 
1477
1517
 
1478
- #line 477 "parser.rl"
1518
+ #line 517 "parser.rl"
1479
1519
 
1480
1520
 
1481
1521
  /*
@@ -1490,7 +1530,7 @@ static const int JSON_en_main = 1;
1490
1530
  *
1491
1531
  */
1492
1532
 
1493
- inline static VALUE convert_encoding(VALUE source)
1533
+ static VALUE convert_encoding(VALUE source)
1494
1534
  {
1495
1535
  char *ptr = RSTRING_PTR(source);
1496
1536
  long len = RSTRING_LEN(source);
@@ -1500,28 +1540,28 @@ inline static VALUE convert_encoding(VALUE source)
1500
1540
  #ifdef HAVE_RUBY_ENCODING_H
1501
1541
  {
1502
1542
  VALUE encoding = rb_funcall(source, i_encoding, 0);
1503
- if (encoding == mEncoding_ASCII_8BIT) {
1543
+ if (encoding == CEncoding_ASCII_8BIT) {
1504
1544
  if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1505
1545
  source = rb_str_dup(source);
1506
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32BE);
1507
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1546
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
1547
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1508
1548
  } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1509
1549
  source = rb_str_dup(source);
1510
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16BE);
1511
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1550
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
1551
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1512
1552
  } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1513
1553
  source = rb_str_dup(source);
1514
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_32LE);
1515
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1554
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
1555
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1516
1556
  } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1517
1557
  source = rb_str_dup(source);
1518
- rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_16LE);
1519
- source = rb_funcall(source, i_encode_bang, 1, mEncoding_UTF_8);
1558
+ rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
1559
+ source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
1520
1560
  } else {
1521
- source = rb_funcall(source, i_force_encoding, 1, mEncoding_UTF_8);
1561
+ FORCE_UTF8(source);
1522
1562
  }
1523
1563
  } else {
1524
- source = rb_funcall(source, i_encode, 1, mEncoding_UTF_8);
1564
+ source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
1525
1565
  }
1526
1566
  }
1527
1567
  #else
@@ -1569,7 +1609,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1569
1609
  char *ptr;
1570
1610
  long len;
1571
1611
  VALUE source, opts;
1572
- GET_STRUCT;
1612
+ GET_PARSER;
1573
1613
  rb_scan_args(argc, argv, "11", &source, &opts);
1574
1614
  source = convert_encoding(StringValue(source));
1575
1615
  ptr = RSTRING_PTR(source);
@@ -1654,19 +1694,19 @@ static VALUE cParser_parse(VALUE self)
1654
1694
  char *p, *pe;
1655
1695
  int cs = EVIL;
1656
1696
  VALUE result = Qnil;
1657
- GET_STRUCT;
1697
+ GET_PARSER;
1658
1698
 
1659
1699
 
1660
- #line 1661 "parser.c"
1700
+ #line 1701 "parser.c"
1661
1701
  {
1662
1702
  cs = JSON_start;
1663
1703
  }
1664
1704
 
1665
- #line 658 "parser.rl"
1705
+ #line 698 "parser.rl"
1666
1706
  p = json->source;
1667
1707
  pe = p + json->len;
1668
1708
 
1669
- #line 1670 "parser.c"
1709
+ #line 1710 "parser.c"
1670
1710
  {
1671
1711
  if ( p == pe )
1672
1712
  goto _test_eof;
@@ -1722,7 +1762,7 @@ case 5:
1722
1762
  goto st1;
1723
1763
  goto st5;
1724
1764
  tr3:
1725
- #line 466 "parser.rl"
1765
+ #line 506 "parser.rl"
1726
1766
  {
1727
1767
  char *np;
1728
1768
  json->current_nesting = 1;
@@ -1731,7 +1771,7 @@ tr3:
1731
1771
  }
1732
1772
  goto st10;
1733
1773
  tr4:
1734
- #line 459 "parser.rl"
1774
+ #line 499 "parser.rl"
1735
1775
  {
1736
1776
  char *np;
1737
1777
  json->current_nesting = 1;
@@ -1743,7 +1783,7 @@ st10:
1743
1783
  if ( ++p == pe )
1744
1784
  goto _test_eof10;
1745
1785
  case 10:
1746
- #line 1747 "parser.c"
1786
+ #line 1787 "parser.c"
1747
1787
  switch( (*p) ) {
1748
1788
  case 13: goto st10;
1749
1789
  case 32: goto st10;
@@ -1800,16 +1840,17 @@ case 9:
1800
1840
  _out: {}
1801
1841
  }
1802
1842
 
1803
- #line 661 "parser.rl"
1843
+ #line 701 "parser.rl"
1804
1844
 
1805
1845
  if (cs >= JSON_first_final && p == pe) {
1806
1846
  return result;
1807
1847
  } else {
1808
1848
  rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1849
+ return Qnil;
1809
1850
  }
1810
1851
  }
1811
1852
 
1812
- inline static JSON_Parser *JSON_allocate()
1853
+ static JSON_Parser *JSON_allocate()
1813
1854
  {
1814
1855
  JSON_Parser *json = ALLOC(JSON_Parser);
1815
1856
  MEMZERO(json, JSON_Parser, 1);
@@ -1843,7 +1884,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
1843
1884
  */
1844
1885
  static VALUE cParser_source(VALUE self)
1845
1886
  {
1846
- GET_STRUCT;
1887
+ GET_PARSER;
1847
1888
  return rb_str_dup(json->Vsource);
1848
1889
  }
1849
1890
 
@@ -1877,12 +1918,12 @@ void Init_parser()
1877
1918
  i_key_p = rb_intern("key?");
1878
1919
  i_deep_const_get = rb_intern("deep_const_get");
1879
1920
  #ifdef HAVE_RUBY_ENCODING_H
1880
- mEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1881
- mEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
1882
- mEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
1883
- mEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
1884
- mEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
1885
- mEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
1921
+ CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
1922
+ CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
1923
+ CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
1924
+ CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
1925
+ CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
1926
+ CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
1886
1927
  i_encoding = rb_intern("encoding");
1887
1928
  i_encode = rb_intern("encode");
1888
1929
  i_encode_bang = rb_intern("encode!");