json 1.8.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -10
- data/{CHANGES → CHANGES.md} +183 -90
- data/Gemfile +11 -5
- data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
- data/{README.rdoc → README.md} +147 -113
- data/Rakefile +32 -36
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +46 -61
- data/ext/json/ext/generator/generator.h +7 -2
- data/ext/json/ext/parser/extconf.rb +3 -0
- data/ext/json/ext/parser/parser.c +353 -460
- data/ext/json/ext/parser/parser.h +4 -5
- data/ext/json/ext/parser/parser.rl +111 -181
- data/ext/json/extconf.rb +0 -1
- data/java/src/json/ext/ByteListTranscoder.java +1 -2
- data/java/src/json/ext/Generator.java +11 -12
- data/java/src/json/ext/GeneratorMethods.java +1 -2
- data/java/src/json/ext/GeneratorService.java +1 -2
- data/java/src/json/ext/GeneratorState.java +3 -56
- data/java/src/json/ext/OptionsReader.java +2 -3
- data/java/src/json/ext/Parser.java +135 -418
- data/java/src/json/ext/Parser.rl +48 -124
- data/java/src/json/ext/ParserService.java +1 -2
- data/java/src/json/ext/RuntimeInfo.java +1 -6
- data/java/src/json/ext/StringDecoder.java +1 -2
- data/java/src/json/ext/StringEncoder.java +5 -0
- data/java/src/json/ext/Utils.java +1 -2
- data/json-java.gemspec +15 -0
- data/json.gemspec +0 -0
- data/json_pure.gemspec +24 -26
- data/lib/json/add/bigdecimal.rb +1 -0
- data/lib/json/add/complex.rb +2 -1
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +2 -2
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +1 -0
- data/lib/json/add/regexp.rb +1 -1
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -1
- data/lib/json/add/time.rb +1 -1
- data/lib/json/common.rb +24 -52
- data/lib/json/ext.rb +0 -6
- data/lib/json/generic_object.rb +5 -4
- data/lib/json/pure/generator.rb +61 -125
- data/lib/json/pure/parser.rb +33 -81
- data/lib/json/pure.rb +2 -8
- data/lib/json/version.rb +2 -1
- data/lib/json.rb +1 -0
- data/references/rfc7159.txt +899 -0
- data/tests/fixtures/obsolete_fail1.json +1 -0
- data/tests/{test_json_addition.rb → json_addition_test.rb} +22 -25
- data/tests/json_common_interface_test.rb +126 -0
- data/tests/json_encoding_test.rb +107 -0
- data/tests/json_ext_parser_test.rb +15 -0
- data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
- data/tests/{test_json_generate.rb → json_generator_test.rb} +79 -39
- data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
- data/tests/json_parser_test.rb +471 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/{setup_variant.rb → test_helper.rb} +10 -0
- data/tools/diff.sh +18 -0
- data/tools/fuzz.rb +1 -9
- metadata +28 -43
- data/COPYING +0 -58
- data/COPYING-json-jruby +0 -57
- data/GPL +0 -340
- data/TODO +0 -1
- data/tests/fixtures/fail1.json +0 -1
- data/tests/test_json.rb +0 -553
- data/tests/test_json_encoding.rb +0 -65
- data/tests/test_json_string_matching.rb +0 -39
- data/tests/test_json_unicode.rb +0 -72
@@ -3,6 +3,28 @@
|
|
3
3
|
#include "../fbuffer/fbuffer.h"
|
4
4
|
#include "parser.h"
|
5
5
|
|
6
|
+
#if defined HAVE_RUBY_ENCODING_H
|
7
|
+
# define EXC_ENCODING rb_utf8_encoding(),
|
8
|
+
# ifndef HAVE_RB_ENC_RAISE
|
9
|
+
static void
|
10
|
+
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
11
|
+
{
|
12
|
+
va_list args;
|
13
|
+
VALUE mesg;
|
14
|
+
|
15
|
+
va_start(args, fmt);
|
16
|
+
mesg = rb_enc_vsprintf(enc, fmt, args);
|
17
|
+
va_end(args);
|
18
|
+
|
19
|
+
rb_exc_raise(rb_exc_new3(exc, mesg));
|
20
|
+
}
|
21
|
+
# define rb_enc_raise enc_raise
|
22
|
+
# endif
|
23
|
+
#else
|
24
|
+
# define EXC_ENCODING /* nothing */
|
25
|
+
# define rb_enc_raise rb_raise
|
26
|
+
#endif
|
27
|
+
|
6
28
|
/* unicode */
|
7
29
|
|
8
30
|
static const char digit_values[256] = {
|
@@ -67,28 +89,21 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
67
89
|
return len;
|
68
90
|
}
|
69
91
|
|
70
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
71
|
-
static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
|
72
|
-
CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
|
73
|
-
static ID i_encoding, i_encode;
|
74
|
-
#else
|
75
|
-
static ID i_iconv;
|
76
|
-
#endif
|
77
|
-
|
78
92
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
79
93
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
80
94
|
|
81
95
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
82
|
-
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
83
|
-
i_object_class, i_array_class,
|
84
|
-
i_match_string, i_aset, i_aref,
|
96
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
97
|
+
i_object_class, i_array_class, i_decimal_class, i_key_p,
|
98
|
+
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
99
|
+
i_leftshift, i_new;
|
85
100
|
|
86
101
|
|
87
|
-
#line
|
102
|
+
#line 125 "parser.rl"
|
88
103
|
|
89
104
|
|
90
105
|
|
91
|
-
#line
|
106
|
+
#line 107 "parser.c"
|
92
107
|
enum {JSON_object_start = 1};
|
93
108
|
enum {JSON_object_first_final = 27};
|
94
109
|
enum {JSON_object_error = 0};
|
@@ -96,30 +111,30 @@ enum {JSON_object_error = 0};
|
|
96
111
|
enum {JSON_object_en_main = 1};
|
97
112
|
|
98
113
|
|
99
|
-
#line
|
114
|
+
#line 166 "parser.rl"
|
100
115
|
|
101
116
|
|
102
|
-
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
117
|
+
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
103
118
|
{
|
104
119
|
int cs = EVIL;
|
105
120
|
VALUE last_name = Qnil;
|
106
121
|
VALUE object_class = json->object_class;
|
107
122
|
|
108
|
-
if (json->max_nesting &&
|
109
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
123
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
124
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
110
125
|
}
|
111
126
|
|
112
127
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
113
128
|
|
114
129
|
|
115
|
-
#line
|
130
|
+
#line 131 "parser.c"
|
116
131
|
{
|
117
132
|
cs = JSON_object_start;
|
118
133
|
}
|
119
134
|
|
120
|
-
#line
|
135
|
+
#line 181 "parser.rl"
|
121
136
|
|
122
|
-
#line
|
137
|
+
#line 138 "parser.c"
|
123
138
|
{
|
124
139
|
if ( p == pe )
|
125
140
|
goto _test_eof;
|
@@ -147,7 +162,7 @@ case 2:
|
|
147
162
|
goto st2;
|
148
163
|
goto st0;
|
149
164
|
tr2:
|
150
|
-
#line
|
165
|
+
#line 148 "parser.rl"
|
151
166
|
{
|
152
167
|
char *np;
|
153
168
|
json->parsing_name = 1;
|
@@ -160,7 +175,7 @@ st3:
|
|
160
175
|
if ( ++p == pe )
|
161
176
|
goto _test_eof3;
|
162
177
|
case 3:
|
163
|
-
#line
|
178
|
+
#line 179 "parser.c"
|
164
179
|
switch( (*p) ) {
|
165
180
|
case 13: goto st3;
|
166
181
|
case 32: goto st3;
|
@@ -227,10 +242,10 @@ case 8:
|
|
227
242
|
goto st8;
|
228
243
|
goto st0;
|
229
244
|
tr11:
|
230
|
-
#line
|
245
|
+
#line 133 "parser.rl"
|
231
246
|
{
|
232
247
|
VALUE v = Qnil;
|
233
|
-
char *np = JSON_parse_value(json, p, pe, &v);
|
248
|
+
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
234
249
|
if (np == NULL) {
|
235
250
|
p--; {p++; cs = 9; goto _out;}
|
236
251
|
} else {
|
@@ -247,7 +262,7 @@ st9:
|
|
247
262
|
if ( ++p == pe )
|
248
263
|
goto _test_eof9;
|
249
264
|
case 9:
|
250
|
-
#line
|
265
|
+
#line 266 "parser.c"
|
251
266
|
switch( (*p) ) {
|
252
267
|
case 13: goto st9;
|
253
268
|
case 32: goto st9;
|
@@ -336,14 +351,14 @@ case 18:
|
|
336
351
|
goto st9;
|
337
352
|
goto st18;
|
338
353
|
tr4:
|
339
|
-
#line
|
354
|
+
#line 156 "parser.rl"
|
340
355
|
{ p--; {p++; cs = 27; goto _out;} }
|
341
356
|
goto st27;
|
342
357
|
st27:
|
343
358
|
if ( ++p == pe )
|
344
359
|
goto _test_eof27;
|
345
360
|
case 27:
|
346
|
-
#line
|
361
|
+
#line 362 "parser.c"
|
347
362
|
goto st0;
|
348
363
|
st19:
|
349
364
|
if ( ++p == pe )
|
@@ -441,7 +456,7 @@ case 26:
|
|
441
456
|
_out: {}
|
442
457
|
}
|
443
458
|
|
444
|
-
#line
|
459
|
+
#line 182 "parser.rl"
|
445
460
|
|
446
461
|
if (cs >= JSON_object_first_final) {
|
447
462
|
if (json->create_additions) {
|
@@ -466,281 +481,358 @@ case 26:
|
|
466
481
|
|
467
482
|
|
468
483
|
|
469
|
-
#line
|
484
|
+
#line 485 "parser.c"
|
470
485
|
enum {JSON_value_start = 1};
|
471
|
-
enum {JSON_value_first_final =
|
486
|
+
enum {JSON_value_first_final = 29};
|
472
487
|
enum {JSON_value_error = 0};
|
473
488
|
|
474
489
|
enum {JSON_value_en_main = 1};
|
475
490
|
|
476
491
|
|
477
|
-
#line
|
492
|
+
#line 282 "parser.rl"
|
478
493
|
|
479
494
|
|
480
|
-
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
495
|
+
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
481
496
|
{
|
482
497
|
int cs = EVIL;
|
483
498
|
|
484
499
|
|
485
|
-
#line
|
500
|
+
#line 501 "parser.c"
|
486
501
|
{
|
487
502
|
cs = JSON_value_start;
|
488
503
|
}
|
489
504
|
|
490
|
-
#line
|
505
|
+
#line 289 "parser.rl"
|
491
506
|
|
492
|
-
#line
|
507
|
+
#line 508 "parser.c"
|
493
508
|
{
|
494
509
|
if ( p == pe )
|
495
510
|
goto _test_eof;
|
496
511
|
switch ( cs )
|
497
512
|
{
|
513
|
+
st1:
|
514
|
+
if ( ++p == pe )
|
515
|
+
goto _test_eof1;
|
498
516
|
case 1:
|
499
517
|
switch( (*p) ) {
|
500
|
-
case
|
501
|
-
case
|
502
|
-
case
|
503
|
-
case
|
504
|
-
case
|
505
|
-
case
|
506
|
-
case
|
507
|
-
case
|
508
|
-
case
|
518
|
+
case 13: goto st1;
|
519
|
+
case 32: goto st1;
|
520
|
+
case 34: goto tr2;
|
521
|
+
case 45: goto tr3;
|
522
|
+
case 47: goto st6;
|
523
|
+
case 73: goto st10;
|
524
|
+
case 78: goto st17;
|
525
|
+
case 91: goto tr7;
|
526
|
+
case 102: goto st19;
|
527
|
+
case 110: goto st23;
|
528
|
+
case 116: goto st26;
|
529
|
+
case 123: goto tr11;
|
509
530
|
}
|
510
|
-
if (
|
511
|
-
|
531
|
+
if ( (*p) > 10 ) {
|
532
|
+
if ( 48 <= (*p) && (*p) <= 57 )
|
533
|
+
goto tr3;
|
534
|
+
} else if ( (*p) >= 9 )
|
535
|
+
goto st1;
|
512
536
|
goto st0;
|
513
537
|
st0:
|
514
538
|
cs = 0;
|
515
539
|
goto _out;
|
516
|
-
|
517
|
-
#line
|
540
|
+
tr2:
|
541
|
+
#line 234 "parser.rl"
|
518
542
|
{
|
519
543
|
char *np = JSON_parse_string(json, p, pe, result);
|
520
|
-
if (np == NULL) { p--; {p++; cs =
|
544
|
+
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
521
545
|
}
|
522
|
-
goto
|
523
|
-
|
524
|
-
#line
|
546
|
+
goto st29;
|
547
|
+
tr3:
|
548
|
+
#line 239 "parser.rl"
|
525
549
|
{
|
526
550
|
char *np;
|
527
|
-
if(pe > p +
|
551
|
+
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
528
552
|
if (json->allow_nan) {
|
529
553
|
*result = CMinusInfinity;
|
530
554
|
{p = (( p + 10))-1;}
|
531
|
-
p--; {p++; cs =
|
555
|
+
p--; {p++; cs = 29; goto _out;}
|
532
556
|
} else {
|
533
|
-
|
557
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
534
558
|
}
|
535
559
|
}
|
536
560
|
np = JSON_parse_float(json, p, pe, result);
|
537
561
|
if (np != NULL) {p = (( np))-1;}
|
538
562
|
np = JSON_parse_integer(json, p, pe, result);
|
539
563
|
if (np != NULL) {p = (( np))-1;}
|
540
|
-
p--; {p++; cs =
|
564
|
+
p--; {p++; cs = 29; goto _out;}
|
541
565
|
}
|
542
|
-
goto
|
543
|
-
|
544
|
-
#line
|
566
|
+
goto st29;
|
567
|
+
tr7:
|
568
|
+
#line 257 "parser.rl"
|
545
569
|
{
|
546
570
|
char *np;
|
547
|
-
json
|
548
|
-
np =
|
549
|
-
json->current_nesting--;
|
550
|
-
if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
|
571
|
+
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
572
|
+
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
551
573
|
}
|
552
|
-
goto
|
553
|
-
|
554
|
-
#line
|
574
|
+
goto st29;
|
575
|
+
tr11:
|
576
|
+
#line 263 "parser.rl"
|
555
577
|
{
|
556
578
|
char *np;
|
557
|
-
json
|
558
|
-
np =
|
559
|
-
json->current_nesting--;
|
560
|
-
if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
|
579
|
+
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
580
|
+
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
561
581
|
}
|
562
|
-
goto
|
563
|
-
|
564
|
-
#line
|
582
|
+
goto st29;
|
583
|
+
tr25:
|
584
|
+
#line 227 "parser.rl"
|
565
585
|
{
|
566
586
|
if (json->allow_nan) {
|
567
587
|
*result = CInfinity;
|
568
588
|
} else {
|
569
|
-
|
589
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
|
570
590
|
}
|
571
591
|
}
|
572
|
-
goto
|
573
|
-
|
574
|
-
#line
|
592
|
+
goto st29;
|
593
|
+
tr27:
|
594
|
+
#line 220 "parser.rl"
|
575
595
|
{
|
576
596
|
if (json->allow_nan) {
|
577
597
|
*result = CNaN;
|
578
598
|
} else {
|
579
|
-
|
599
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
|
580
600
|
}
|
581
601
|
}
|
582
|
-
goto
|
583
|
-
|
584
|
-
#line
|
602
|
+
goto st29;
|
603
|
+
tr31:
|
604
|
+
#line 214 "parser.rl"
|
585
605
|
{
|
586
606
|
*result = Qfalse;
|
587
607
|
}
|
588
|
-
goto
|
589
|
-
|
590
|
-
#line
|
608
|
+
goto st29;
|
609
|
+
tr34:
|
610
|
+
#line 211 "parser.rl"
|
591
611
|
{
|
592
612
|
*result = Qnil;
|
593
613
|
}
|
594
|
-
goto
|
595
|
-
|
596
|
-
#line
|
614
|
+
goto st29;
|
615
|
+
tr37:
|
616
|
+
#line 217 "parser.rl"
|
597
617
|
{
|
598
618
|
*result = Qtrue;
|
599
619
|
}
|
600
|
-
goto
|
601
|
-
|
602
|
-
if ( ++p == pe )
|
603
|
-
goto
|
604
|
-
case
|
605
|
-
#line
|
606
|
-
{ p--; {p++; cs =
|
607
|
-
#line
|
620
|
+
goto st29;
|
621
|
+
st29:
|
622
|
+
if ( ++p == pe )
|
623
|
+
goto _test_eof29;
|
624
|
+
case 29:
|
625
|
+
#line 269 "parser.rl"
|
626
|
+
{ p--; {p++; cs = 29; goto _out;} }
|
627
|
+
#line 628 "parser.c"
|
628
|
+
switch( (*p) ) {
|
629
|
+
case 13: goto st29;
|
630
|
+
case 32: goto st29;
|
631
|
+
case 47: goto st2;
|
632
|
+
}
|
633
|
+
if ( 9 <= (*p) && (*p) <= 10 )
|
634
|
+
goto st29;
|
608
635
|
goto st0;
|
609
636
|
st2:
|
610
637
|
if ( ++p == pe )
|
611
638
|
goto _test_eof2;
|
612
639
|
case 2:
|
613
|
-
|
614
|
-
goto st3;
|
640
|
+
switch( (*p) ) {
|
641
|
+
case 42: goto st3;
|
642
|
+
case 47: goto st5;
|
643
|
+
}
|
615
644
|
goto st0;
|
616
645
|
st3:
|
617
646
|
if ( ++p == pe )
|
618
647
|
goto _test_eof3;
|
619
648
|
case 3:
|
620
|
-
if ( (*p) ==
|
649
|
+
if ( (*p) == 42 )
|
621
650
|
goto st4;
|
622
|
-
goto
|
651
|
+
goto st3;
|
623
652
|
st4:
|
624
653
|
if ( ++p == pe )
|
625
654
|
goto _test_eof4;
|
626
655
|
case 4:
|
627
|
-
|
628
|
-
goto
|
629
|
-
|
656
|
+
switch( (*p) ) {
|
657
|
+
case 42: goto st4;
|
658
|
+
case 47: goto st29;
|
659
|
+
}
|
660
|
+
goto st3;
|
630
661
|
st5:
|
631
662
|
if ( ++p == pe )
|
632
663
|
goto _test_eof5;
|
633
664
|
case 5:
|
634
|
-
if ( (*p) ==
|
635
|
-
goto
|
636
|
-
goto
|
665
|
+
if ( (*p) == 10 )
|
666
|
+
goto st29;
|
667
|
+
goto st5;
|
637
668
|
st6:
|
638
669
|
if ( ++p == pe )
|
639
670
|
goto _test_eof6;
|
640
671
|
case 6:
|
641
|
-
|
642
|
-
goto st7;
|
672
|
+
switch( (*p) ) {
|
673
|
+
case 42: goto st7;
|
674
|
+
case 47: goto st9;
|
675
|
+
}
|
643
676
|
goto st0;
|
644
677
|
st7:
|
645
678
|
if ( ++p == pe )
|
646
679
|
goto _test_eof7;
|
647
680
|
case 7:
|
648
|
-
if ( (*p) ==
|
681
|
+
if ( (*p) == 42 )
|
649
682
|
goto st8;
|
650
|
-
goto
|
683
|
+
goto st7;
|
651
684
|
st8:
|
652
685
|
if ( ++p == pe )
|
653
686
|
goto _test_eof8;
|
654
687
|
case 8:
|
655
|
-
|
656
|
-
goto
|
657
|
-
|
688
|
+
switch( (*p) ) {
|
689
|
+
case 42: goto st8;
|
690
|
+
case 47: goto st1;
|
691
|
+
}
|
692
|
+
goto st7;
|
658
693
|
st9:
|
659
694
|
if ( ++p == pe )
|
660
695
|
goto _test_eof9;
|
661
696
|
case 9:
|
662
|
-
if ( (*p) ==
|
663
|
-
goto
|
664
|
-
goto
|
697
|
+
if ( (*p) == 10 )
|
698
|
+
goto st1;
|
699
|
+
goto st9;
|
665
700
|
st10:
|
666
701
|
if ( ++p == pe )
|
667
702
|
goto _test_eof10;
|
668
703
|
case 10:
|
669
|
-
if ( (*p) ==
|
670
|
-
goto
|
704
|
+
if ( (*p) == 110 )
|
705
|
+
goto st11;
|
671
706
|
goto st0;
|
672
707
|
st11:
|
673
708
|
if ( ++p == pe )
|
674
709
|
goto _test_eof11;
|
675
710
|
case 11:
|
676
|
-
if ( (*p) ==
|
711
|
+
if ( (*p) == 102 )
|
677
712
|
goto st12;
|
678
713
|
goto st0;
|
679
714
|
st12:
|
680
715
|
if ( ++p == pe )
|
681
716
|
goto _test_eof12;
|
682
717
|
case 12:
|
683
|
-
if ( (*p) ==
|
718
|
+
if ( (*p) == 105 )
|
684
719
|
goto st13;
|
685
720
|
goto st0;
|
686
721
|
st13:
|
687
722
|
if ( ++p == pe )
|
688
723
|
goto _test_eof13;
|
689
724
|
case 13:
|
690
|
-
if ( (*p) ==
|
725
|
+
if ( (*p) == 110 )
|
691
726
|
goto st14;
|
692
727
|
goto st0;
|
693
728
|
st14:
|
694
729
|
if ( ++p == pe )
|
695
730
|
goto _test_eof14;
|
696
731
|
case 14:
|
697
|
-
if ( (*p) ==
|
698
|
-
goto
|
732
|
+
if ( (*p) == 105 )
|
733
|
+
goto st15;
|
699
734
|
goto st0;
|
700
735
|
st15:
|
701
736
|
if ( ++p == pe )
|
702
737
|
goto _test_eof15;
|
703
738
|
case 15:
|
704
|
-
if ( (*p) ==
|
739
|
+
if ( (*p) == 116 )
|
705
740
|
goto st16;
|
706
741
|
goto st0;
|
707
742
|
st16:
|
708
743
|
if ( ++p == pe )
|
709
744
|
goto _test_eof16;
|
710
745
|
case 16:
|
711
|
-
if ( (*p) ==
|
712
|
-
goto
|
746
|
+
if ( (*p) == 121 )
|
747
|
+
goto tr25;
|
713
748
|
goto st0;
|
714
749
|
st17:
|
715
750
|
if ( ++p == pe )
|
716
751
|
goto _test_eof17;
|
717
752
|
case 17:
|
718
|
-
if ( (*p) ==
|
719
|
-
goto
|
753
|
+
if ( (*p) == 97 )
|
754
|
+
goto st18;
|
720
755
|
goto st0;
|
721
756
|
st18:
|
722
757
|
if ( ++p == pe )
|
723
758
|
goto _test_eof18;
|
724
759
|
case 18:
|
725
|
-
if ( (*p) ==
|
726
|
-
goto
|
760
|
+
if ( (*p) == 78 )
|
761
|
+
goto tr27;
|
727
762
|
goto st0;
|
728
763
|
st19:
|
729
764
|
if ( ++p == pe )
|
730
765
|
goto _test_eof19;
|
731
766
|
case 19:
|
732
|
-
if ( (*p) ==
|
767
|
+
if ( (*p) == 97 )
|
733
768
|
goto st20;
|
734
769
|
goto st0;
|
735
770
|
st20:
|
736
771
|
if ( ++p == pe )
|
737
772
|
goto _test_eof20;
|
738
773
|
case 20:
|
774
|
+
if ( (*p) == 108 )
|
775
|
+
goto st21;
|
776
|
+
goto st0;
|
777
|
+
st21:
|
778
|
+
if ( ++p == pe )
|
779
|
+
goto _test_eof21;
|
780
|
+
case 21:
|
781
|
+
if ( (*p) == 115 )
|
782
|
+
goto st22;
|
783
|
+
goto st0;
|
784
|
+
st22:
|
785
|
+
if ( ++p == pe )
|
786
|
+
goto _test_eof22;
|
787
|
+
case 22:
|
788
|
+
if ( (*p) == 101 )
|
789
|
+
goto tr31;
|
790
|
+
goto st0;
|
791
|
+
st23:
|
792
|
+
if ( ++p == pe )
|
793
|
+
goto _test_eof23;
|
794
|
+
case 23:
|
795
|
+
if ( (*p) == 117 )
|
796
|
+
goto st24;
|
797
|
+
goto st0;
|
798
|
+
st24:
|
799
|
+
if ( ++p == pe )
|
800
|
+
goto _test_eof24;
|
801
|
+
case 24:
|
802
|
+
if ( (*p) == 108 )
|
803
|
+
goto st25;
|
804
|
+
goto st0;
|
805
|
+
st25:
|
806
|
+
if ( ++p == pe )
|
807
|
+
goto _test_eof25;
|
808
|
+
case 25:
|
809
|
+
if ( (*p) == 108 )
|
810
|
+
goto tr34;
|
811
|
+
goto st0;
|
812
|
+
st26:
|
813
|
+
if ( ++p == pe )
|
814
|
+
goto _test_eof26;
|
815
|
+
case 26:
|
816
|
+
if ( (*p) == 114 )
|
817
|
+
goto st27;
|
818
|
+
goto st0;
|
819
|
+
st27:
|
820
|
+
if ( ++p == pe )
|
821
|
+
goto _test_eof27;
|
822
|
+
case 27:
|
823
|
+
if ( (*p) == 117 )
|
824
|
+
goto st28;
|
825
|
+
goto st0;
|
826
|
+
st28:
|
827
|
+
if ( ++p == pe )
|
828
|
+
goto _test_eof28;
|
829
|
+
case 28:
|
739
830
|
if ( (*p) == 101 )
|
740
|
-
goto
|
831
|
+
goto tr37;
|
741
832
|
goto st0;
|
742
833
|
}
|
743
|
-
|
834
|
+
_test_eof1: cs = 1; goto _test_eof;
|
835
|
+
_test_eof29: cs = 29; goto _test_eof;
|
744
836
|
_test_eof2: cs = 2; goto _test_eof;
|
745
837
|
_test_eof3: cs = 3; goto _test_eof;
|
746
838
|
_test_eof4: cs = 4; goto _test_eof;
|
@@ -760,12 +852,20 @@ case 20:
|
|
760
852
|
_test_eof18: cs = 18; goto _test_eof;
|
761
853
|
_test_eof19: cs = 19; goto _test_eof;
|
762
854
|
_test_eof20: cs = 20; goto _test_eof;
|
855
|
+
_test_eof21: cs = 21; goto _test_eof;
|
856
|
+
_test_eof22: cs = 22; goto _test_eof;
|
857
|
+
_test_eof23: cs = 23; goto _test_eof;
|
858
|
+
_test_eof24: cs = 24; goto _test_eof;
|
859
|
+
_test_eof25: cs = 25; goto _test_eof;
|
860
|
+
_test_eof26: cs = 26; goto _test_eof;
|
861
|
+
_test_eof27: cs = 27; goto _test_eof;
|
862
|
+
_test_eof28: cs = 28; goto _test_eof;
|
763
863
|
|
764
864
|
_test_eof: {}
|
765
865
|
_out: {}
|
766
866
|
}
|
767
867
|
|
768
|
-
#line
|
868
|
+
#line 290 "parser.rl"
|
769
869
|
|
770
870
|
if (cs >= JSON_value_first_final) {
|
771
871
|
return p;
|
@@ -775,7 +875,7 @@ case 20:
|
|
775
875
|
}
|
776
876
|
|
777
877
|
|
778
|
-
#line
|
878
|
+
#line 879 "parser.c"
|
779
879
|
enum {JSON_integer_start = 1};
|
780
880
|
enum {JSON_integer_first_final = 3};
|
781
881
|
enum {JSON_integer_error = 0};
|
@@ -783,7 +883,7 @@ enum {JSON_integer_error = 0};
|
|
783
883
|
enum {JSON_integer_en_main = 1};
|
784
884
|
|
785
885
|
|
786
|
-
#line
|
886
|
+
#line 306 "parser.rl"
|
787
887
|
|
788
888
|
|
789
889
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -791,15 +891,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
791
891
|
int cs = EVIL;
|
792
892
|
|
793
893
|
|
794
|
-
#line
|
894
|
+
#line 895 "parser.c"
|
795
895
|
{
|
796
896
|
cs = JSON_integer_start;
|
797
897
|
}
|
798
898
|
|
799
|
-
#line
|
899
|
+
#line 313 "parser.rl"
|
800
900
|
json->memo = p;
|
801
901
|
|
802
|
-
#line
|
902
|
+
#line 903 "parser.c"
|
803
903
|
{
|
804
904
|
if ( p == pe )
|
805
905
|
goto _test_eof;
|
@@ -833,14 +933,14 @@ case 3:
|
|
833
933
|
goto st0;
|
834
934
|
goto tr4;
|
835
935
|
tr4:
|
836
|
-
#line
|
936
|
+
#line 303 "parser.rl"
|
837
937
|
{ p--; {p++; cs = 4; goto _out;} }
|
838
938
|
goto st4;
|
839
939
|
st4:
|
840
940
|
if ( ++p == pe )
|
841
941
|
goto _test_eof4;
|
842
942
|
case 4:
|
843
|
-
#line
|
943
|
+
#line 944 "parser.c"
|
844
944
|
goto st0;
|
845
945
|
st5:
|
846
946
|
if ( ++p == pe )
|
@@ -859,7 +959,7 @@ case 5:
|
|
859
959
|
_out: {}
|
860
960
|
}
|
861
961
|
|
862
|
-
#line
|
962
|
+
#line 315 "parser.rl"
|
863
963
|
|
864
964
|
if (cs >= JSON_integer_first_final) {
|
865
965
|
long len = p - json->memo;
|
@@ -874,7 +974,7 @@ case 5:
|
|
874
974
|
}
|
875
975
|
|
876
976
|
|
877
|
-
#line
|
977
|
+
#line 978 "parser.c"
|
878
978
|
enum {JSON_float_start = 1};
|
879
979
|
enum {JSON_float_first_final = 8};
|
880
980
|
enum {JSON_float_error = 0};
|
@@ -882,7 +982,7 @@ enum {JSON_float_error = 0};
|
|
882
982
|
enum {JSON_float_en_main = 1};
|
883
983
|
|
884
984
|
|
885
|
-
#line
|
985
|
+
#line 340 "parser.rl"
|
886
986
|
|
887
987
|
|
888
988
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -890,15 +990,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
890
990
|
int cs = EVIL;
|
891
991
|
|
892
992
|
|
893
|
-
#line
|
993
|
+
#line 994 "parser.c"
|
894
994
|
{
|
895
995
|
cs = JSON_float_start;
|
896
996
|
}
|
897
997
|
|
898
|
-
#line
|
998
|
+
#line 347 "parser.rl"
|
899
999
|
json->memo = p;
|
900
1000
|
|
901
|
-
#line
|
1001
|
+
#line 1002 "parser.c"
|
902
1002
|
{
|
903
1003
|
if ( p == pe )
|
904
1004
|
goto _test_eof;
|
@@ -956,14 +1056,14 @@ case 8:
|
|
956
1056
|
goto st0;
|
957
1057
|
goto tr9;
|
958
1058
|
tr9:
|
959
|
-
#line
|
1059
|
+
#line 334 "parser.rl"
|
960
1060
|
{ p--; {p++; cs = 9; goto _out;} }
|
961
1061
|
goto st9;
|
962
1062
|
st9:
|
963
1063
|
if ( ++p == pe )
|
964
1064
|
goto _test_eof9;
|
965
1065
|
case 9:
|
966
|
-
#line
|
1066
|
+
#line 1067 "parser.c"
|
967
1067
|
goto st0;
|
968
1068
|
st5:
|
969
1069
|
if ( ++p == pe )
|
@@ -1024,14 +1124,20 @@ case 7:
|
|
1024
1124
|
_out: {}
|
1025
1125
|
}
|
1026
1126
|
|
1027
|
-
#line
|
1127
|
+
#line 349 "parser.rl"
|
1028
1128
|
|
1029
1129
|
if (cs >= JSON_float_first_final) {
|
1030
1130
|
long len = p - json->memo;
|
1031
1131
|
fbuffer_clear(json->fbuffer);
|
1032
1132
|
fbuffer_append(json->fbuffer, json->memo, len);
|
1033
1133
|
fbuffer_append_char(json->fbuffer, '\0');
|
1034
|
-
|
1134
|
+
if (NIL_P(json->decimal_class)) {
|
1135
|
+
*result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1136
|
+
} else {
|
1137
|
+
VALUE text;
|
1138
|
+
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1139
|
+
*result = rb_funcall(json->decimal_class, i_new, 1, text);
|
1140
|
+
}
|
1035
1141
|
return p + 1;
|
1036
1142
|
} else {
|
1037
1143
|
return NULL;
|
@@ -1040,7 +1146,7 @@ case 7:
|
|
1040
1146
|
|
1041
1147
|
|
1042
1148
|
|
1043
|
-
#line
|
1149
|
+
#line 1150 "parser.c"
|
1044
1150
|
enum {JSON_array_start = 1};
|
1045
1151
|
enum {JSON_array_first_final = 17};
|
1046
1152
|
enum {JSON_array_error = 0};
|
@@ -1048,28 +1154,28 @@ enum {JSON_array_error = 0};
|
|
1048
1154
|
enum {JSON_array_en_main = 1};
|
1049
1155
|
|
1050
1156
|
|
1051
|
-
#line
|
1157
|
+
#line 398 "parser.rl"
|
1052
1158
|
|
1053
1159
|
|
1054
|
-
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
1160
|
+
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
1055
1161
|
{
|
1056
1162
|
int cs = EVIL;
|
1057
1163
|
VALUE array_class = json->array_class;
|
1058
1164
|
|
1059
|
-
if (json->max_nesting &&
|
1060
|
-
rb_raise(eNestingError, "nesting of %d is too deep",
|
1165
|
+
if (json->max_nesting && current_nesting > json->max_nesting) {
|
1166
|
+
rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
|
1061
1167
|
}
|
1062
1168
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1063
1169
|
|
1064
1170
|
|
1065
|
-
#line
|
1171
|
+
#line 1172 "parser.c"
|
1066
1172
|
{
|
1067
1173
|
cs = JSON_array_start;
|
1068
1174
|
}
|
1069
1175
|
|
1070
|
-
#line
|
1176
|
+
#line 411 "parser.rl"
|
1071
1177
|
|
1072
|
-
#line
|
1178
|
+
#line 1179 "parser.c"
|
1073
1179
|
{
|
1074
1180
|
if ( p == pe )
|
1075
1181
|
goto _test_eof;
|
@@ -1108,10 +1214,10 @@ case 2:
|
|
1108
1214
|
goto st2;
|
1109
1215
|
goto st0;
|
1110
1216
|
tr2:
|
1111
|
-
#line
|
1217
|
+
#line 375 "parser.rl"
|
1112
1218
|
{
|
1113
1219
|
VALUE v = Qnil;
|
1114
|
-
char *np = JSON_parse_value(json, p, pe, &v);
|
1220
|
+
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
1115
1221
|
if (np == NULL) {
|
1116
1222
|
p--; {p++; cs = 3; goto _out;}
|
1117
1223
|
} else {
|
@@ -1128,7 +1234,7 @@ st3:
|
|
1128
1234
|
if ( ++p == pe )
|
1129
1235
|
goto _test_eof3;
|
1130
1236
|
case 3:
|
1131
|
-
#line
|
1237
|
+
#line 1238 "parser.c"
|
1132
1238
|
switch( (*p) ) {
|
1133
1239
|
case 13: goto st3;
|
1134
1240
|
case 32: goto st3;
|
@@ -1228,14 +1334,14 @@ case 12:
|
|
1228
1334
|
goto st3;
|
1229
1335
|
goto st12;
|
1230
1336
|
tr4:
|
1231
|
-
#line
|
1337
|
+
#line 390 "parser.rl"
|
1232
1338
|
{ p--; {p++; cs = 17; goto _out;} }
|
1233
1339
|
goto st17;
|
1234
1340
|
st17:
|
1235
1341
|
if ( ++p == pe )
|
1236
1342
|
goto _test_eof17;
|
1237
1343
|
case 17:
|
1238
|
-
#line
|
1344
|
+
#line 1345 "parser.c"
|
1239
1345
|
goto st0;
|
1240
1346
|
st13:
|
1241
1347
|
if ( ++p == pe )
|
@@ -1291,12 +1397,12 @@ case 16:
|
|
1291
1397
|
_out: {}
|
1292
1398
|
}
|
1293
1399
|
|
1294
|
-
#line
|
1400
|
+
#line 412 "parser.rl"
|
1295
1401
|
|
1296
1402
|
if(cs >= JSON_array_first_final) {
|
1297
1403
|
return p + 1;
|
1298
1404
|
} else {
|
1299
|
-
|
1405
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
1300
1406
|
return NULL;
|
1301
1407
|
}
|
1302
1408
|
}
|
@@ -1336,13 +1442,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1336
1442
|
break;
|
1337
1443
|
case 'u':
|
1338
1444
|
if (pe > stringEnd - 4) {
|
1339
|
-
|
1445
|
+
rb_enc_raise(
|
1446
|
+
EXC_ENCODING eParserError,
|
1447
|
+
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
1448
|
+
);
|
1340
1449
|
} else {
|
1341
1450
|
UTF32 ch = unescape_unicode((unsigned char *) ++pe);
|
1342
1451
|
pe += 3;
|
1343
1452
|
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
1344
1453
|
pe++;
|
1345
|
-
if (pe > stringEnd - 6)
|
1454
|
+
if (pe > stringEnd - 6) {
|
1455
|
+
rb_enc_raise(
|
1456
|
+
EXC_ENCODING eParserError,
|
1457
|
+
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
1458
|
+
);
|
1459
|
+
}
|
1346
1460
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
1347
1461
|
UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
|
1348
1462
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
@@ -1372,7 +1486,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1372
1486
|
}
|
1373
1487
|
|
1374
1488
|
|
1375
|
-
#line
|
1489
|
+
#line 1490 "parser.c"
|
1376
1490
|
enum {JSON_string_start = 1};
|
1377
1491
|
enum {JSON_string_first_final = 8};
|
1378
1492
|
enum {JSON_string_error = 0};
|
@@ -1380,7 +1494,7 @@ enum {JSON_string_error = 0};
|
|
1380
1494
|
enum {JSON_string_en_main = 1};
|
1381
1495
|
|
1382
1496
|
|
1383
|
-
#line
|
1497
|
+
#line 519 "parser.rl"
|
1384
1498
|
|
1385
1499
|
|
1386
1500
|
static int
|
@@ -1402,15 +1516,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1402
1516
|
|
1403
1517
|
*result = rb_str_buf_new(0);
|
1404
1518
|
|
1405
|
-
#line
|
1519
|
+
#line 1520 "parser.c"
|
1406
1520
|
{
|
1407
1521
|
cs = JSON_string_start;
|
1408
1522
|
}
|
1409
1523
|
|
1410
|
-
#line
|
1524
|
+
#line 540 "parser.rl"
|
1411
1525
|
json->memo = p;
|
1412
1526
|
|
1413
|
-
#line
|
1527
|
+
#line 1528 "parser.c"
|
1414
1528
|
{
|
1415
1529
|
if ( p == pe )
|
1416
1530
|
goto _test_eof;
|
@@ -1435,7 +1549,7 @@ case 2:
|
|
1435
1549
|
goto st0;
|
1436
1550
|
goto st2;
|
1437
1551
|
tr2:
|
1438
|
-
#line
|
1552
|
+
#line 505 "parser.rl"
|
1439
1553
|
{
|
1440
1554
|
*result = json_string_unescape(*result, json->memo + 1, p);
|
1441
1555
|
if (NIL_P(*result)) {
|
@@ -1446,14 +1560,14 @@ tr2:
|
|
1446
1560
|
{p = (( p + 1))-1;}
|
1447
1561
|
}
|
1448
1562
|
}
|
1449
|
-
#line
|
1563
|
+
#line 516 "parser.rl"
|
1450
1564
|
{ p--; {p++; cs = 8; goto _out;} }
|
1451
1565
|
goto st8;
|
1452
1566
|
st8:
|
1453
1567
|
if ( ++p == pe )
|
1454
1568
|
goto _test_eof8;
|
1455
1569
|
case 8:
|
1456
|
-
#line
|
1570
|
+
#line 1571 "parser.c"
|
1457
1571
|
goto st0;
|
1458
1572
|
st3:
|
1459
1573
|
if ( ++p == pe )
|
@@ -1529,7 +1643,7 @@ case 7:
|
|
1529
1643
|
_out: {}
|
1530
1644
|
}
|
1531
1645
|
|
1532
|
-
#line
|
1646
|
+
#line 542 "parser.rl"
|
1533
1647
|
|
1534
1648
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1535
1649
|
VALUE klass;
|
@@ -1544,6 +1658,8 @@ case 7:
|
|
1544
1658
|
|
1545
1659
|
if (json->symbolize_names && json->parsing_name) {
|
1546
1660
|
*result = rb_str_intern(*result);
|
1661
|
+
} else {
|
1662
|
+
rb_str_resize(*result, RSTRING_LEN(*result));
|
1547
1663
|
}
|
1548
1664
|
if (cs >= JSON_string_first_final) {
|
1549
1665
|
return p + 1;
|
@@ -1566,41 +1682,16 @@ case 7:
|
|
1566
1682
|
|
1567
1683
|
static VALUE convert_encoding(VALUE source)
|
1568
1684
|
{
|
1569
|
-
char *ptr = RSTRING_PTR(source);
|
1570
|
-
long len = RSTRING_LEN(source);
|
1571
|
-
if (len < 2) {
|
1572
|
-
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
1573
|
-
}
|
1574
1685
|
#ifdef HAVE_RUBY_ENCODING_H
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
|
1580
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1581
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
|
1582
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1583
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
|
1584
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1585
|
-
source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
|
1586
|
-
} else {
|
1587
|
-
source = rb_str_dup(source);
|
1588
|
-
FORCE_UTF8(source);
|
1589
|
-
}
|
1590
|
-
} else {
|
1591
|
-
source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
|
1592
|
-
}
|
1593
|
-
}
|
1594
|
-
#else
|
1595
|
-
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
1596
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
|
1597
|
-
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
1598
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
|
1599
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
1600
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
|
1601
|
-
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
1602
|
-
source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
|
1686
|
+
rb_encoding *enc = rb_enc_get(source);
|
1687
|
+
if (enc == rb_ascii8bit_encoding()) {
|
1688
|
+
if (OBJ_FROZEN(source)) {
|
1689
|
+
source = rb_str_dup(source);
|
1603
1690
|
}
|
1691
|
+
FORCE_UTF8(source);
|
1692
|
+
} else {
|
1693
|
+
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
1694
|
+
}
|
1604
1695
|
#endif
|
1605
1696
|
return source;
|
1606
1697
|
}
|
@@ -1623,8 +1714,9 @@ static VALUE convert_encoding(VALUE source)
|
|
1623
1714
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
1624
1715
|
* false.
|
1625
1716
|
* * *symbolize_names*: If set to true, returns symbols for the names
|
1626
|
-
* (keys) in a JSON object. Otherwise strings are returned, which is
|
1627
|
-
* the default.
|
1717
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is
|
1718
|
+
* also the default. It's not possible to use this option in
|
1719
|
+
* conjunction with the *create_additions* option.
|
1628
1720
|
* * *create_additions*: If set to false, the Parser doesn't create
|
1629
1721
|
* additions even if a matching class and create_id was found. This option
|
1630
1722
|
* defaults to false.
|
@@ -1639,12 +1731,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1639
1731
|
if (json->Vsource) {
|
1640
1732
|
rb_raise(rb_eTypeError, "already initialized instance");
|
1641
1733
|
}
|
1734
|
+
#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
1735
|
+
rb_scan_args(argc, argv, "1:", &source, &opts);
|
1736
|
+
#else
|
1642
1737
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
1738
|
+
#endif
|
1643
1739
|
if (!NIL_P(opts)) {
|
1740
|
+
#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
1644
1741
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
1645
1742
|
if (NIL_P(opts)) {
|
1646
1743
|
rb_raise(rb_eArgError, "opts needs to be like a hash");
|
1647
1744
|
} else {
|
1745
|
+
#endif
|
1648
1746
|
VALUE tmp = ID2SYM(i_max_nesting);
|
1649
1747
|
if (option_given_p(opts, tmp)) {
|
1650
1748
|
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
@@ -1669,19 +1767,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1669
1767
|
} else {
|
1670
1768
|
json->symbolize_names = 0;
|
1671
1769
|
}
|
1672
|
-
tmp = ID2SYM(i_quirks_mode);
|
1673
|
-
if (option_given_p(opts, tmp)) {
|
1674
|
-
VALUE quirks_mode = rb_hash_aref(opts, tmp);
|
1675
|
-
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
1676
|
-
} else {
|
1677
|
-
json->quirks_mode = 0;
|
1678
|
-
}
|
1679
1770
|
tmp = ID2SYM(i_create_additions);
|
1680
1771
|
if (option_given_p(opts, tmp)) {
|
1681
1772
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
1682
1773
|
} else {
|
1683
1774
|
json->create_additions = 0;
|
1684
1775
|
}
|
1776
|
+
if (json->symbolize_names && json->create_additions) {
|
1777
|
+
rb_raise(rb_eArgError,
|
1778
|
+
"options :symbolize_names and :create_additions cannot be "
|
1779
|
+
" used in conjunction");
|
1780
|
+
}
|
1685
1781
|
tmp = ID2SYM(i_create_id);
|
1686
1782
|
if (option_given_p(opts, tmp)) {
|
1687
1783
|
json->create_id = rb_hash_aref(opts, tmp);
|
@@ -1700,6 +1796,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1700
1796
|
} else {
|
1701
1797
|
json->array_class = Qnil;
|
1702
1798
|
}
|
1799
|
+
tmp = ID2SYM(i_decimal_class);
|
1800
|
+
if (option_given_p(opts, tmp)) {
|
1801
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
1802
|
+
} else {
|
1803
|
+
json->decimal_class = Qnil;
|
1804
|
+
}
|
1703
1805
|
tmp = ID2SYM(i_match_string);
|
1704
1806
|
if (option_given_p(opts, tmp)) {
|
1705
1807
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
@@ -1707,7 +1809,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1707
1809
|
} else {
|
1708
1810
|
json->match_string = Qnil;
|
1709
1811
|
}
|
1812
|
+
#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
1710
1813
|
}
|
1814
|
+
#endif
|
1711
1815
|
} else {
|
1712
1816
|
json->max_nesting = 100;
|
1713
1817
|
json->allow_nan = 0;
|
@@ -1715,12 +1819,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1715
1819
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1716
1820
|
json->object_class = Qnil;
|
1717
1821
|
json->array_class = Qnil;
|
1822
|
+
json->decimal_class = Qnil;
|
1718
1823
|
}
|
1719
|
-
source =
|
1720
|
-
if (!json->quirks_mode) {
|
1721
|
-
source = convert_encoding(StringValue(source));
|
1722
|
-
}
|
1723
|
-
json->current_nesting = 0;
|
1824
|
+
source = convert_encoding(StringValue(source));
|
1724
1825
|
StringValue(source);
|
1725
1826
|
json->len = RSTRING_LEN(source);
|
1726
1827
|
json->source = RSTRING_PTR(source);;
|
@@ -1729,7 +1830,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1729
1830
|
}
|
1730
1831
|
|
1731
1832
|
|
1732
|
-
#line
|
1833
|
+
#line 1834 "parser.c"
|
1733
1834
|
enum {JSON_start = 1};
|
1734
1835
|
enum {JSON_first_final = 10};
|
1735
1836
|
enum {JSON_error = 0};
|
@@ -1737,201 +1838,33 @@ enum {JSON_error = 0};
|
|
1737
1838
|
enum {JSON_en_main = 1};
|
1738
1839
|
|
1739
1840
|
|
1740
|
-
#line
|
1841
|
+
#line 742 "parser.rl"
|
1741
1842
|
|
1742
1843
|
|
1743
|
-
|
1844
|
+
/*
|
1845
|
+
* call-seq: parse()
|
1846
|
+
*
|
1847
|
+
* Parses the current JSON text _source_ and returns the complete data
|
1848
|
+
* structure as a result.
|
1849
|
+
*/
|
1850
|
+
static VALUE cParser_parse(VALUE self)
|
1744
1851
|
{
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1852
|
+
char *p, *pe;
|
1853
|
+
int cs = EVIL;
|
1854
|
+
VALUE result = Qnil;
|
1855
|
+
GET_PARSER;
|
1749
1856
|
|
1750
1857
|
|
1751
|
-
#line
|
1858
|
+
#line 1859 "parser.c"
|
1752
1859
|
{
|
1753
1860
|
cs = JSON_start;
|
1754
1861
|
}
|
1755
1862
|
|
1756
|
-
#line
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
#line 1761 "parser.c"
|
1761
|
-
{
|
1762
|
-
if ( p == pe )
|
1763
|
-
goto _test_eof;
|
1764
|
-
switch ( cs )
|
1765
|
-
{
|
1766
|
-
st1:
|
1767
|
-
if ( ++p == pe )
|
1768
|
-
goto _test_eof1;
|
1769
|
-
case 1:
|
1770
|
-
switch( (*p) ) {
|
1771
|
-
case 13: goto st1;
|
1772
|
-
case 32: goto st1;
|
1773
|
-
case 47: goto st2;
|
1774
|
-
case 91: goto tr3;
|
1775
|
-
case 123: goto tr4;
|
1776
|
-
}
|
1777
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
1778
|
-
goto st1;
|
1779
|
-
goto st0;
|
1780
|
-
st0:
|
1781
|
-
cs = 0;
|
1782
|
-
goto _out;
|
1783
|
-
st2:
|
1784
|
-
if ( ++p == pe )
|
1785
|
-
goto _test_eof2;
|
1786
|
-
case 2:
|
1787
|
-
switch( (*p) ) {
|
1788
|
-
case 42: goto st3;
|
1789
|
-
case 47: goto st5;
|
1790
|
-
}
|
1791
|
-
goto st0;
|
1792
|
-
st3:
|
1793
|
-
if ( ++p == pe )
|
1794
|
-
goto _test_eof3;
|
1795
|
-
case 3:
|
1796
|
-
if ( (*p) == 42 )
|
1797
|
-
goto st4;
|
1798
|
-
goto st3;
|
1799
|
-
st4:
|
1800
|
-
if ( ++p == pe )
|
1801
|
-
goto _test_eof4;
|
1802
|
-
case 4:
|
1803
|
-
switch( (*p) ) {
|
1804
|
-
case 42: goto st4;
|
1805
|
-
case 47: goto st1;
|
1806
|
-
}
|
1807
|
-
goto st3;
|
1808
|
-
st5:
|
1809
|
-
if ( ++p == pe )
|
1810
|
-
goto _test_eof5;
|
1811
|
-
case 5:
|
1812
|
-
if ( (*p) == 10 )
|
1813
|
-
goto st1;
|
1814
|
-
goto st5;
|
1815
|
-
tr3:
|
1816
|
-
#line 729 "parser.rl"
|
1817
|
-
{
|
1818
|
-
char *np;
|
1819
|
-
json->current_nesting = 1;
|
1820
|
-
np = JSON_parse_array(json, p, pe, &result);
|
1821
|
-
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1822
|
-
}
|
1823
|
-
goto st10;
|
1824
|
-
tr4:
|
1825
|
-
#line 722 "parser.rl"
|
1826
|
-
{
|
1827
|
-
char *np;
|
1828
|
-
json->current_nesting = 1;
|
1829
|
-
np = JSON_parse_object(json, p, pe, &result);
|
1830
|
-
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1831
|
-
}
|
1832
|
-
goto st10;
|
1833
|
-
st10:
|
1834
|
-
if ( ++p == pe )
|
1835
|
-
goto _test_eof10;
|
1836
|
-
case 10:
|
1837
|
-
#line 1838 "parser.c"
|
1838
|
-
switch( (*p) ) {
|
1839
|
-
case 13: goto st10;
|
1840
|
-
case 32: goto st10;
|
1841
|
-
case 47: goto st6;
|
1842
|
-
}
|
1843
|
-
if ( 9 <= (*p) && (*p) <= 10 )
|
1844
|
-
goto st10;
|
1845
|
-
goto st0;
|
1846
|
-
st6:
|
1847
|
-
if ( ++p == pe )
|
1848
|
-
goto _test_eof6;
|
1849
|
-
case 6:
|
1850
|
-
switch( (*p) ) {
|
1851
|
-
case 42: goto st7;
|
1852
|
-
case 47: goto st9;
|
1853
|
-
}
|
1854
|
-
goto st0;
|
1855
|
-
st7:
|
1856
|
-
if ( ++p == pe )
|
1857
|
-
goto _test_eof7;
|
1858
|
-
case 7:
|
1859
|
-
if ( (*p) == 42 )
|
1860
|
-
goto st8;
|
1861
|
-
goto st7;
|
1862
|
-
st8:
|
1863
|
-
if ( ++p == pe )
|
1864
|
-
goto _test_eof8;
|
1865
|
-
case 8:
|
1866
|
-
switch( (*p) ) {
|
1867
|
-
case 42: goto st8;
|
1868
|
-
case 47: goto st10;
|
1869
|
-
}
|
1870
|
-
goto st7;
|
1871
|
-
st9:
|
1872
|
-
if ( ++p == pe )
|
1873
|
-
goto _test_eof9;
|
1874
|
-
case 9:
|
1875
|
-
if ( (*p) == 10 )
|
1876
|
-
goto st10;
|
1877
|
-
goto st9;
|
1878
|
-
}
|
1879
|
-
_test_eof1: cs = 1; goto _test_eof;
|
1880
|
-
_test_eof2: cs = 2; goto _test_eof;
|
1881
|
-
_test_eof3: cs = 3; goto _test_eof;
|
1882
|
-
_test_eof4: cs = 4; goto _test_eof;
|
1883
|
-
_test_eof5: cs = 5; goto _test_eof;
|
1884
|
-
_test_eof10: cs = 10; goto _test_eof;
|
1885
|
-
_test_eof6: cs = 6; goto _test_eof;
|
1886
|
-
_test_eof7: cs = 7; goto _test_eof;
|
1887
|
-
_test_eof8: cs = 8; goto _test_eof;
|
1888
|
-
_test_eof9: cs = 9; goto _test_eof;
|
1889
|
-
|
1890
|
-
_test_eof: {}
|
1891
|
-
_out: {}
|
1892
|
-
}
|
1893
|
-
|
1894
|
-
#line 753 "parser.rl"
|
1895
|
-
|
1896
|
-
if (cs >= JSON_first_final && p == pe) {
|
1897
|
-
return result;
|
1898
|
-
} else {
|
1899
|
-
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
1900
|
-
return Qnil;
|
1901
|
-
}
|
1902
|
-
}
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
#line 1907 "parser.c"
|
1907
|
-
enum {JSON_quirks_mode_start = 1};
|
1908
|
-
enum {JSON_quirks_mode_first_final = 10};
|
1909
|
-
enum {JSON_quirks_mode_error = 0};
|
1910
|
-
|
1911
|
-
enum {JSON_quirks_mode_en_main = 1};
|
1912
|
-
|
1913
|
-
|
1914
|
-
#line 778 "parser.rl"
|
1915
|
-
|
1916
|
-
|
1917
|
-
static VALUE cParser_parse_quirks_mode(VALUE self)
|
1918
|
-
{
|
1919
|
-
char *p, *pe;
|
1920
|
-
int cs = EVIL;
|
1921
|
-
VALUE result = Qnil;
|
1922
|
-
GET_PARSER;
|
1923
|
-
|
1924
|
-
|
1925
|
-
#line 1926 "parser.c"
|
1926
|
-
{
|
1927
|
-
cs = JSON_quirks_mode_start;
|
1928
|
-
}
|
1929
|
-
|
1930
|
-
#line 788 "parser.rl"
|
1931
|
-
p = json->source;
|
1932
|
-
pe = p + json->len;
|
1863
|
+
#line 758 "parser.rl"
|
1864
|
+
p = json->source;
|
1865
|
+
pe = p + json->len;
|
1933
1866
|
|
1934
|
-
#line
|
1867
|
+
#line 1868 "parser.c"
|
1935
1868
|
{
|
1936
1869
|
if ( p == pe )
|
1937
1870
|
goto _test_eof;
|
@@ -1965,9 +1898,9 @@ st0:
|
|
1965
1898
|
cs = 0;
|
1966
1899
|
goto _out;
|
1967
1900
|
tr2:
|
1968
|
-
#line
|
1901
|
+
#line 734 "parser.rl"
|
1969
1902
|
{
|
1970
|
-
char *np = JSON_parse_value(json, p, pe, &result);
|
1903
|
+
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
1971
1904
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
1972
1905
|
}
|
1973
1906
|
goto st10;
|
@@ -1975,7 +1908,7 @@ st10:
|
|
1975
1908
|
if ( ++p == pe )
|
1976
1909
|
goto _test_eof10;
|
1977
1910
|
case 10:
|
1978
|
-
#line
|
1911
|
+
#line 1912 "parser.c"
|
1979
1912
|
switch( (*p) ) {
|
1980
1913
|
case 13: goto st10;
|
1981
1914
|
case 32: goto st10;
|
@@ -2064,30 +1997,13 @@ case 9:
|
|
2064
1997
|
_out: {}
|
2065
1998
|
}
|
2066
1999
|
|
2067
|
-
#line
|
2000
|
+
#line 761 "parser.rl"
|
2068
2001
|
|
2069
|
-
|
2070
|
-
|
2071
|
-
} else {
|
2072
|
-
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
2073
|
-
return Qnil;
|
2074
|
-
}
|
2075
|
-
}
|
2076
|
-
|
2077
|
-
/*
|
2078
|
-
* call-seq: parse()
|
2079
|
-
*
|
2080
|
-
* Parses the current JSON text _source_ and returns the complete data
|
2081
|
-
* structure as a result.
|
2082
|
-
*/
|
2083
|
-
static VALUE cParser_parse(VALUE self)
|
2084
|
-
{
|
2085
|
-
GET_PARSER;
|
2086
|
-
|
2087
|
-
if (json->quirks_mode) {
|
2088
|
-
return cParser_parse_quirks_mode(self);
|
2002
|
+
if (cs >= JSON_first_final && p == pe) {
|
2003
|
+
return result;
|
2089
2004
|
} else {
|
2090
|
-
|
2005
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
2006
|
+
return Qnil;
|
2091
2007
|
}
|
2092
2008
|
}
|
2093
2009
|
|
@@ -2098,6 +2014,7 @@ static void JSON_mark(void *ptr)
|
|
2098
2014
|
rb_gc_mark_maybe(json->create_id);
|
2099
2015
|
rb_gc_mark_maybe(json->object_class);
|
2100
2016
|
rb_gc_mark_maybe(json->array_class);
|
2017
|
+
rb_gc_mark_maybe(json->decimal_class);
|
2101
2018
|
rb_gc_mark_maybe(json->match_string);
|
2102
2019
|
}
|
2103
2020
|
|
@@ -2145,18 +2062,6 @@ static VALUE cParser_source(VALUE self)
|
|
2145
2062
|
return rb_str_dup(json->Vsource);
|
2146
2063
|
}
|
2147
2064
|
|
2148
|
-
/*
|
2149
|
-
* call-seq: quirks_mode?()
|
2150
|
-
*
|
2151
|
-
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
2152
|
-
*/
|
2153
|
-
static VALUE cParser_quirks_mode_p(VALUE self)
|
2154
|
-
{
|
2155
|
-
GET_PARSER;
|
2156
|
-
return json->quirks_mode ? Qtrue : Qfalse;
|
2157
|
-
}
|
2158
|
-
|
2159
|
-
|
2160
2065
|
void Init_parser(void)
|
2161
2066
|
{
|
2162
2067
|
rb_require("json/common");
|
@@ -2169,7 +2074,6 @@ void Init_parser(void)
|
|
2169
2074
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
2170
2075
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2171
2076
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2172
|
-
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
2173
2077
|
|
2174
2078
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2175
2079
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
@@ -2183,9 +2087,9 @@ void Init_parser(void)
|
|
2183
2087
|
i_max_nesting = rb_intern("max_nesting");
|
2184
2088
|
i_allow_nan = rb_intern("allow_nan");
|
2185
2089
|
i_symbolize_names = rb_intern("symbolize_names");
|
2186
|
-
i_quirks_mode = rb_intern("quirks_mode");
|
2187
2090
|
i_object_class = rb_intern("object_class");
|
2188
2091
|
i_array_class = rb_intern("array_class");
|
2092
|
+
i_decimal_class = rb_intern("decimal_class");
|
2189
2093
|
i_match = rb_intern("match");
|
2190
2094
|
i_match_string = rb_intern("match_string");
|
2191
2095
|
i_key_p = rb_intern("key?");
|
@@ -2193,18 +2097,7 @@ void Init_parser(void)
|
|
2193
2097
|
i_aset = rb_intern("[]=");
|
2194
2098
|
i_aref = rb_intern("[]");
|
2195
2099
|
i_leftshift = rb_intern("<<");
|
2196
|
-
|
2197
|
-
CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
|
2198
|
-
CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
|
2199
|
-
CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
|
2200
|
-
CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
|
2201
|
-
CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
|
2202
|
-
CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
|
2203
|
-
i_encoding = rb_intern("encoding");
|
2204
|
-
i_encode = rb_intern("encode");
|
2205
|
-
#else
|
2206
|
-
i_iconv = rb_intern("iconv");
|
2207
|
-
#endif
|
2100
|
+
i_new = rb_intern("new");
|
2208
2101
|
}
|
2209
2102
|
|
2210
2103
|
/*
|