json 2.0.3 → 2.5.1
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.
- checksums.yaml +5 -5
- data/CHANGES.md +66 -0
- data/Gemfile +1 -3
- data/LICENSE +56 -0
- data/README.md +54 -21
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +229 -54
- data/ext/json/ext/generator/generator.h +5 -3
- data/ext/json/ext/parser/extconf.rb +25 -0
- data/ext/json/ext/parser/parser.c +180 -85
- data/ext/json/ext/parser/parser.h +2 -0
- data/ext/json/ext/parser/parser.rl +104 -9
- data/ext/json/extconf.rb +1 -0
- data/json.gemspec +0 -0
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +2 -3
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/rational.rb +2 -3
- data/lib/json/add/regexp.rb +2 -2
- data/lib/json/add/set.rb +29 -0
- data/lib/json/common.rb +372 -125
- data/lib/json/pure/generator.rb +31 -10
- data/lib/json/pure/parser.rb +35 -5
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +549 -29
- data/tests/fixtures/fail29.json +1 -0
- data/tests/fixtures/fail30.json +1 -0
- data/tests/fixtures/fail31.json +1 -0
- data/tests/fixtures/fail32.json +1 -0
- data/tests/json_addition_test.rb +6 -0
- data/tests/json_common_interface_test.rb +47 -4
- data/tests/json_encoding_test.rb +2 -0
- data/tests/json_fixtures_test.rb +9 -1
- data/tests/json_generator_test.rb +30 -8
- data/tests/json_parser_test.rb +43 -12
- data/tests/lib/core_assertions.rb +763 -0
- data/tests/lib/envutil.rb +365 -0
- data/tests/lib/find_executable.rb +22 -0
- data/tests/lib/helper.rb +4 -0
- data/tests/ractor_test.rb +30 -0
- data/tests/test_helper.rb +3 -7
- metadata +31 -44
- data/.gitignore +0 -17
- data/.travis.yml +0 -19
- data/README-json-jruby.md +0 -33
- data/Rakefile +0 -408
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- data/diagrams/.keep +0 -0
- data/install.rb +0 -23
- data/java/src/json/ext/ByteListTranscoder.java +0 -166
- data/java/src/json/ext/Generator.java +0 -443
- data/java/src/json/ext/GeneratorMethods.java +0 -231
- data/java/src/json/ext/GeneratorService.java +0 -42
- data/java/src/json/ext/GeneratorState.java +0 -490
- data/java/src/json/ext/OptionsReader.java +0 -113
- data/java/src/json/ext/Parser.java +0 -2347
- data/java/src/json/ext/Parser.rl +0 -878
- data/java/src/json/ext/ParserService.java +0 -34
- data/java/src/json/ext/RuntimeInfo.java +0 -116
- data/java/src/json/ext/StringDecoder.java +0 -166
- data/java/src/json/ext/StringEncoder.java +0 -111
- data/java/src/json/ext/Utils.java +0 -88
- data/json-java.gemspec +0 -38
- data/json_pure.gemspec +0 -38
- data/references/rfc7159.txt +0 -899
- data/tools/diff.sh +0 -18
- data/tools/fuzz.rb +0 -131
- data/tools/server.rb +0 -62
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
/* This file is automatically generated from parser.rl by using ragel */
|
2
2
|
#line 1 "parser.rl"
|
3
3
|
#include "../fbuffer/fbuffer.h"
|
4
4
|
#include "parser.h"
|
@@ -27,7 +27,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
|
27
27
|
|
28
28
|
/* unicode */
|
29
29
|
|
30
|
-
static const char digit_values[256] = {
|
30
|
+
static const signed char digit_values[256] = {
|
31
31
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
32
32
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
33
33
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
|
@@ -46,7 +46,7 @@ static const char digit_values[256] = {
|
|
46
46
|
|
47
47
|
static UTF32 unescape_unicode(const unsigned char *p)
|
48
48
|
{
|
49
|
-
char b;
|
49
|
+
signed char b;
|
50
50
|
UTF32 result = 0;
|
51
51
|
b = digit_values[p[0]];
|
52
52
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
@@ -94,15 +94,16 @@ static VALUE CNaN, CInfinity, CMinusInfinity;
|
|
94
94
|
|
95
95
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
96
96
|
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
97
|
-
i_object_class, i_array_class,
|
98
|
-
i_match_string, i_aset, i_aref,
|
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, i_try_convert, i_freeze, i_uminus;
|
99
100
|
|
100
101
|
|
101
|
-
#line
|
102
|
+
#line 126 "parser.rl"
|
102
103
|
|
103
104
|
|
104
105
|
|
105
|
-
#line
|
106
|
+
#line 108 "parser.c"
|
106
107
|
enum {JSON_object_start = 1};
|
107
108
|
enum {JSON_object_first_final = 27};
|
108
109
|
enum {JSON_object_error = 0};
|
@@ -110,7 +111,7 @@ enum {JSON_object_error = 0};
|
|
110
111
|
enum {JSON_object_en_main = 1};
|
111
112
|
|
112
113
|
|
113
|
-
#line
|
114
|
+
#line 168 "parser.rl"
|
114
115
|
|
115
116
|
|
116
117
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -126,14 +127,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
126
127
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
127
128
|
|
128
129
|
|
129
|
-
#line
|
130
|
+
#line 132 "parser.c"
|
130
131
|
{
|
131
132
|
cs = JSON_object_start;
|
132
133
|
}
|
133
134
|
|
134
|
-
#line
|
135
|
+
#line 183 "parser.rl"
|
135
136
|
|
136
|
-
#line
|
137
|
+
#line 139 "parser.c"
|
137
138
|
{
|
138
139
|
if ( p == pe )
|
139
140
|
goto _test_eof;
|
@@ -161,7 +162,7 @@ case 2:
|
|
161
162
|
goto st2;
|
162
163
|
goto st0;
|
163
164
|
tr2:
|
164
|
-
#line
|
165
|
+
#line 150 "parser.rl"
|
165
166
|
{
|
166
167
|
char *np;
|
167
168
|
json->parsing_name = 1;
|
@@ -174,7 +175,7 @@ st3:
|
|
174
175
|
if ( ++p == pe )
|
175
176
|
goto _test_eof3;
|
176
177
|
case 3:
|
177
|
-
#line
|
178
|
+
#line 180 "parser.c"
|
178
179
|
switch( (*p) ) {
|
179
180
|
case 13: goto st3;
|
180
181
|
case 32: goto st3;
|
@@ -241,7 +242,7 @@ case 8:
|
|
241
242
|
goto st8;
|
242
243
|
goto st0;
|
243
244
|
tr11:
|
244
|
-
#line
|
245
|
+
#line 134 "parser.rl"
|
245
246
|
{
|
246
247
|
VALUE v = Qnil;
|
247
248
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
@@ -249,6 +250,7 @@ tr11:
|
|
249
250
|
p--; {p++; cs = 9; goto _out;}
|
250
251
|
} else {
|
251
252
|
if (NIL_P(json->object_class)) {
|
253
|
+
OBJ_FREEZE(last_name);
|
252
254
|
rb_hash_aset(*result, last_name, v);
|
253
255
|
} else {
|
254
256
|
rb_funcall(*result, i_aset, 2, last_name, v);
|
@@ -261,7 +263,7 @@ st9:
|
|
261
263
|
if ( ++p == pe )
|
262
264
|
goto _test_eof9;
|
263
265
|
case 9:
|
264
|
-
#line
|
266
|
+
#line 268 "parser.c"
|
265
267
|
switch( (*p) ) {
|
266
268
|
case 13: goto st9;
|
267
269
|
case 32: goto st9;
|
@@ -350,14 +352,14 @@ case 18:
|
|
350
352
|
goto st9;
|
351
353
|
goto st18;
|
352
354
|
tr4:
|
353
|
-
#line
|
355
|
+
#line 158 "parser.rl"
|
354
356
|
{ p--; {p++; cs = 27; goto _out;} }
|
355
357
|
goto st27;
|
356
358
|
st27:
|
357
359
|
if ( ++p == pe )
|
358
360
|
goto _test_eof27;
|
359
361
|
case 27:
|
360
|
-
#line
|
362
|
+
#line 364 "parser.c"
|
361
363
|
goto st0;
|
362
364
|
st19:
|
363
365
|
if ( ++p == pe )
|
@@ -455,7 +457,7 @@ case 26:
|
|
455
457
|
_out: {}
|
456
458
|
}
|
457
459
|
|
458
|
-
#line
|
460
|
+
#line 184 "parser.rl"
|
459
461
|
|
460
462
|
if (cs >= JSON_object_first_final) {
|
461
463
|
if (json->create_additions) {
|
@@ -480,7 +482,7 @@ case 26:
|
|
480
482
|
|
481
483
|
|
482
484
|
|
483
|
-
#line
|
485
|
+
#line 487 "parser.c"
|
484
486
|
enum {JSON_value_start = 1};
|
485
487
|
enum {JSON_value_first_final = 29};
|
486
488
|
enum {JSON_value_error = 0};
|
@@ -488,7 +490,7 @@ enum {JSON_value_error = 0};
|
|
488
490
|
enum {JSON_value_en_main = 1};
|
489
491
|
|
490
492
|
|
491
|
-
#line
|
493
|
+
#line 284 "parser.rl"
|
492
494
|
|
493
495
|
|
494
496
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -496,14 +498,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
496
498
|
int cs = EVIL;
|
497
499
|
|
498
500
|
|
499
|
-
#line
|
501
|
+
#line 503 "parser.c"
|
500
502
|
{
|
501
503
|
cs = JSON_value_start;
|
502
504
|
}
|
503
505
|
|
504
|
-
#line
|
506
|
+
#line 291 "parser.rl"
|
505
507
|
|
506
|
-
#line
|
508
|
+
#line 510 "parser.c"
|
507
509
|
{
|
508
510
|
if ( p == pe )
|
509
511
|
goto _test_eof;
|
@@ -537,14 +539,14 @@ st0:
|
|
537
539
|
cs = 0;
|
538
540
|
goto _out;
|
539
541
|
tr2:
|
540
|
-
#line
|
542
|
+
#line 236 "parser.rl"
|
541
543
|
{
|
542
544
|
char *np = JSON_parse_string(json, p, pe, result);
|
543
545
|
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
544
546
|
}
|
545
547
|
goto st29;
|
546
548
|
tr3:
|
547
|
-
#line
|
549
|
+
#line 241 "parser.rl"
|
548
550
|
{
|
549
551
|
char *np;
|
550
552
|
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -564,7 +566,7 @@ tr3:
|
|
564
566
|
}
|
565
567
|
goto st29;
|
566
568
|
tr7:
|
567
|
-
#line
|
569
|
+
#line 259 "parser.rl"
|
568
570
|
{
|
569
571
|
char *np;
|
570
572
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
@@ -572,7 +574,7 @@ tr7:
|
|
572
574
|
}
|
573
575
|
goto st29;
|
574
576
|
tr11:
|
575
|
-
#line
|
577
|
+
#line 265 "parser.rl"
|
576
578
|
{
|
577
579
|
char *np;
|
578
580
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -580,7 +582,7 @@ tr11:
|
|
580
582
|
}
|
581
583
|
goto st29;
|
582
584
|
tr25:
|
583
|
-
#line
|
585
|
+
#line 229 "parser.rl"
|
584
586
|
{
|
585
587
|
if (json->allow_nan) {
|
586
588
|
*result = CInfinity;
|
@@ -590,7 +592,7 @@ tr25:
|
|
590
592
|
}
|
591
593
|
goto st29;
|
592
594
|
tr27:
|
593
|
-
#line
|
595
|
+
#line 222 "parser.rl"
|
594
596
|
{
|
595
597
|
if (json->allow_nan) {
|
596
598
|
*result = CNaN;
|
@@ -600,19 +602,19 @@ tr27:
|
|
600
602
|
}
|
601
603
|
goto st29;
|
602
604
|
tr31:
|
603
|
-
#line
|
605
|
+
#line 216 "parser.rl"
|
604
606
|
{
|
605
607
|
*result = Qfalse;
|
606
608
|
}
|
607
609
|
goto st29;
|
608
610
|
tr34:
|
609
|
-
#line
|
611
|
+
#line 213 "parser.rl"
|
610
612
|
{
|
611
613
|
*result = Qnil;
|
612
614
|
}
|
613
615
|
goto st29;
|
614
616
|
tr37:
|
615
|
-
#line
|
617
|
+
#line 219 "parser.rl"
|
616
618
|
{
|
617
619
|
*result = Qtrue;
|
618
620
|
}
|
@@ -621,9 +623,9 @@ st29:
|
|
621
623
|
if ( ++p == pe )
|
622
624
|
goto _test_eof29;
|
623
625
|
case 29:
|
624
|
-
#line
|
626
|
+
#line 271 "parser.rl"
|
625
627
|
{ p--; {p++; cs = 29; goto _out;} }
|
626
|
-
#line
|
628
|
+
#line 630 "parser.c"
|
627
629
|
switch( (*p) ) {
|
628
630
|
case 13: goto st29;
|
629
631
|
case 32: goto st29;
|
@@ -864,7 +866,11 @@ case 28:
|
|
864
866
|
_out: {}
|
865
867
|
}
|
866
868
|
|
867
|
-
#line
|
869
|
+
#line 292 "parser.rl"
|
870
|
+
|
871
|
+
if (json->freeze) {
|
872
|
+
OBJ_FREEZE(*result);
|
873
|
+
}
|
868
874
|
|
869
875
|
if (cs >= JSON_value_first_final) {
|
870
876
|
return p;
|
@@ -874,7 +880,7 @@ case 28:
|
|
874
880
|
}
|
875
881
|
|
876
882
|
|
877
|
-
#line
|
883
|
+
#line 885 "parser.c"
|
878
884
|
enum {JSON_integer_start = 1};
|
879
885
|
enum {JSON_integer_first_final = 3};
|
880
886
|
enum {JSON_integer_error = 0};
|
@@ -882,7 +888,7 @@ enum {JSON_integer_error = 0};
|
|
882
888
|
enum {JSON_integer_en_main = 1};
|
883
889
|
|
884
890
|
|
885
|
-
#line
|
891
|
+
#line 312 "parser.rl"
|
886
892
|
|
887
893
|
|
888
894
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -890,15 +896,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
890
896
|
int cs = EVIL;
|
891
897
|
|
892
898
|
|
893
|
-
#line
|
899
|
+
#line 901 "parser.c"
|
894
900
|
{
|
895
901
|
cs = JSON_integer_start;
|
896
902
|
}
|
897
903
|
|
898
|
-
#line
|
904
|
+
#line 319 "parser.rl"
|
899
905
|
json->memo = p;
|
900
906
|
|
901
|
-
#line
|
907
|
+
#line 909 "parser.c"
|
902
908
|
{
|
903
909
|
if ( p == pe )
|
904
910
|
goto _test_eof;
|
@@ -932,14 +938,14 @@ case 3:
|
|
932
938
|
goto st0;
|
933
939
|
goto tr4;
|
934
940
|
tr4:
|
935
|
-
#line
|
941
|
+
#line 309 "parser.rl"
|
936
942
|
{ p--; {p++; cs = 4; goto _out;} }
|
937
943
|
goto st4;
|
938
944
|
st4:
|
939
945
|
if ( ++p == pe )
|
940
946
|
goto _test_eof4;
|
941
947
|
case 4:
|
942
|
-
#line
|
948
|
+
#line 950 "parser.c"
|
943
949
|
goto st0;
|
944
950
|
st5:
|
945
951
|
if ( ++p == pe )
|
@@ -958,7 +964,7 @@ case 5:
|
|
958
964
|
_out: {}
|
959
965
|
}
|
960
966
|
|
961
|
-
#line
|
967
|
+
#line 321 "parser.rl"
|
962
968
|
|
963
969
|
if (cs >= JSON_integer_first_final) {
|
964
970
|
long len = p - json->memo;
|
@@ -973,7 +979,7 @@ case 5:
|
|
973
979
|
}
|
974
980
|
|
975
981
|
|
976
|
-
#line
|
982
|
+
#line 984 "parser.c"
|
977
983
|
enum {JSON_float_start = 1};
|
978
984
|
enum {JSON_float_first_final = 8};
|
979
985
|
enum {JSON_float_error = 0};
|
@@ -981,7 +987,7 @@ enum {JSON_float_error = 0};
|
|
981
987
|
enum {JSON_float_en_main = 1};
|
982
988
|
|
983
989
|
|
984
|
-
#line
|
990
|
+
#line 346 "parser.rl"
|
985
991
|
|
986
992
|
|
987
993
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -989,15 +995,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
989
995
|
int cs = EVIL;
|
990
996
|
|
991
997
|
|
992
|
-
#line
|
998
|
+
#line 1013 "parser.c"
|
993
999
|
{
|
994
1000
|
cs = JSON_float_start;
|
995
1001
|
}
|
996
1002
|
|
997
|
-
#line
|
1003
|
+
#line 366 "parser.rl"
|
998
1004
|
json->memo = p;
|
999
1005
|
|
1000
|
-
#line
|
1006
|
+
#line 1021 "parser.c"
|
1001
1007
|
{
|
1002
1008
|
if ( p == pe )
|
1003
1009
|
goto _test_eof;
|
@@ -1055,14 +1061,14 @@ case 8:
|
|
1055
1061
|
goto st0;
|
1056
1062
|
goto tr9;
|
1057
1063
|
tr9:
|
1058
|
-
#line
|
1064
|
+
#line 340 "parser.rl"
|
1059
1065
|
{ p--; {p++; cs = 9; goto _out;} }
|
1060
1066
|
goto st9;
|
1061
1067
|
st9:
|
1062
1068
|
if ( ++p == pe )
|
1063
1069
|
goto _test_eof9;
|
1064
1070
|
case 9:
|
1065
|
-
#line
|
1071
|
+
#line 1086 "parser.c"
|
1066
1072
|
goto st0;
|
1067
1073
|
st5:
|
1068
1074
|
if ( ++p == pe )
|
@@ -1123,14 +1129,49 @@ case 7:
|
|
1123
1129
|
_out: {}
|
1124
1130
|
}
|
1125
1131
|
|
1126
|
-
#line
|
1132
|
+
#line 368 "parser.rl"
|
1127
1133
|
|
1128
1134
|
if (cs >= JSON_float_first_final) {
|
1135
|
+
VALUE mod = Qnil;
|
1136
|
+
ID method_id = 0;
|
1137
|
+
if (rb_respond_to(json->decimal_class, i_try_convert)) {
|
1138
|
+
mod = json->decimal_class;
|
1139
|
+
method_id = i_try_convert;
|
1140
|
+
} else if (rb_respond_to(json->decimal_class, i_new)) {
|
1141
|
+
mod = json->decimal_class;
|
1142
|
+
method_id = i_new;
|
1143
|
+
} else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
|
1144
|
+
VALUE name = rb_class_name(json->decimal_class);
|
1145
|
+
const char *name_cstr = RSTRING_PTR(name);
|
1146
|
+
const char *last_colon = strrchr(name_cstr, ':');
|
1147
|
+
if (last_colon) {
|
1148
|
+
const char *mod_path_end = last_colon - 1;
|
1149
|
+
VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
|
1150
|
+
mod = rb_path_to_class(mod_path);
|
1151
|
+
|
1152
|
+
const char *method_name_beg = last_colon + 1;
|
1153
|
+
long before_len = method_name_beg - name_cstr;
|
1154
|
+
long len = RSTRING_LEN(name) - before_len;
|
1155
|
+
VALUE method_name = rb_str_substr(name, before_len, len);
|
1156
|
+
method_id = SYM2ID(rb_str_intern(method_name));
|
1157
|
+
} else {
|
1158
|
+
mod = rb_mKernel;
|
1159
|
+
method_id = SYM2ID(rb_str_intern(name));
|
1160
|
+
}
|
1161
|
+
}
|
1162
|
+
|
1129
1163
|
long len = p - json->memo;
|
1130
1164
|
fbuffer_clear(json->fbuffer);
|
1131
1165
|
fbuffer_append(json->fbuffer, json->memo, len);
|
1132
1166
|
fbuffer_append_char(json->fbuffer, '\0');
|
1133
|
-
|
1167
|
+
|
1168
|
+
if (method_id) {
|
1169
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1170
|
+
*result = rb_funcallv(mod, method_id, 1, &text);
|
1171
|
+
} else {
|
1172
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1173
|
+
}
|
1174
|
+
|
1134
1175
|
return p + 1;
|
1135
1176
|
} else {
|
1136
1177
|
return NULL;
|
@@ -1139,7 +1180,7 @@ case 7:
|
|
1139
1180
|
|
1140
1181
|
|
1141
1182
|
|
1142
|
-
#line
|
1183
|
+
#line 1173 "parser.c"
|
1143
1184
|
enum {JSON_array_start = 1};
|
1144
1185
|
enum {JSON_array_first_final = 17};
|
1145
1186
|
enum {JSON_array_error = 0};
|
@@ -1147,7 +1188,7 @@ enum {JSON_array_error = 0};
|
|
1147
1188
|
enum {JSON_array_en_main = 1};
|
1148
1189
|
|
1149
1190
|
|
1150
|
-
#line
|
1191
|
+
#line 421 "parser.rl"
|
1151
1192
|
|
1152
1193
|
|
1153
1194
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -1161,14 +1202,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1161
1202
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1162
1203
|
|
1163
1204
|
|
1164
|
-
#line
|
1205
|
+
#line 1195 "parser.c"
|
1165
1206
|
{
|
1166
1207
|
cs = JSON_array_start;
|
1167
1208
|
}
|
1168
1209
|
|
1169
|
-
#line
|
1210
|
+
#line 434 "parser.rl"
|
1170
1211
|
|
1171
|
-
#line
|
1212
|
+
#line 1202 "parser.c"
|
1172
1213
|
{
|
1173
1214
|
if ( p == pe )
|
1174
1215
|
goto _test_eof;
|
@@ -1207,7 +1248,7 @@ case 2:
|
|
1207
1248
|
goto st2;
|
1208
1249
|
goto st0;
|
1209
1250
|
tr2:
|
1210
|
-
#line
|
1251
|
+
#line 398 "parser.rl"
|
1211
1252
|
{
|
1212
1253
|
VALUE v = Qnil;
|
1213
1254
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
@@ -1227,7 +1268,7 @@ st3:
|
|
1227
1268
|
if ( ++p == pe )
|
1228
1269
|
goto _test_eof3;
|
1229
1270
|
case 3:
|
1230
|
-
#line
|
1271
|
+
#line 1261 "parser.c"
|
1231
1272
|
switch( (*p) ) {
|
1232
1273
|
case 13: goto st3;
|
1233
1274
|
case 32: goto st3;
|
@@ -1327,14 +1368,14 @@ case 12:
|
|
1327
1368
|
goto st3;
|
1328
1369
|
goto st12;
|
1329
1370
|
tr4:
|
1330
|
-
#line
|
1371
|
+
#line 413 "parser.rl"
|
1331
1372
|
{ p--; {p++; cs = 17; goto _out;} }
|
1332
1373
|
goto st17;
|
1333
1374
|
st17:
|
1334
1375
|
if ( ++p == pe )
|
1335
1376
|
goto _test_eof17;
|
1336
1377
|
case 17:
|
1337
|
-
#line
|
1378
|
+
#line 1368 "parser.c"
|
1338
1379
|
goto st0;
|
1339
1380
|
st13:
|
1340
1381
|
if ( ++p == pe )
|
@@ -1390,7 +1431,7 @@ case 16:
|
|
1390
1431
|
_out: {}
|
1391
1432
|
}
|
1392
1433
|
|
1393
|
-
#line
|
1434
|
+
#line 435 "parser.rl"
|
1394
1435
|
|
1395
1436
|
if(cs >= JSON_array_first_final) {
|
1396
1437
|
return p + 1;
|
@@ -1435,13 +1476,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1435
1476
|
break;
|
1436
1477
|
case 'u':
|
1437
1478
|
if (pe > stringEnd - 4) {
|
1438
|
-
|
1479
|
+
rb_enc_raise(
|
1480
|
+
EXC_ENCODING eParserError,
|
1481
|
+
"%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
|
1482
|
+
);
|
1439
1483
|
} else {
|
1440
1484
|
UTF32 ch = unescape_unicode((unsigned char *) ++pe);
|
1441
1485
|
pe += 3;
|
1442
1486
|
if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
|
1443
1487
|
pe++;
|
1444
|
-
if (pe > stringEnd - 6)
|
1488
|
+
if (pe > stringEnd - 6) {
|
1489
|
+
rb_enc_raise(
|
1490
|
+
EXC_ENCODING eParserError,
|
1491
|
+
"%u: incomplete surrogate pair at '%s'", __LINE__, p
|
1492
|
+
);
|
1493
|
+
}
|
1445
1494
|
if (pe[0] == '\\' && pe[1] == 'u') {
|
1446
1495
|
UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
|
1447
1496
|
ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
|
@@ -1471,7 +1520,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1471
1520
|
}
|
1472
1521
|
|
1473
1522
|
|
1474
|
-
#line
|
1523
|
+
#line 1513 "parser.c"
|
1475
1524
|
enum {JSON_string_start = 1};
|
1476
1525
|
enum {JSON_string_first_final = 8};
|
1477
1526
|
enum {JSON_string_error = 0};
|
@@ -1479,7 +1528,7 @@ enum {JSON_string_error = 0};
|
|
1479
1528
|
enum {JSON_string_en_main = 1};
|
1480
1529
|
|
1481
1530
|
|
1482
|
-
#line
|
1531
|
+
#line 542 "parser.rl"
|
1483
1532
|
|
1484
1533
|
|
1485
1534
|
static int
|
@@ -1501,15 +1550,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1501
1550
|
|
1502
1551
|
*result = rb_str_buf_new(0);
|
1503
1552
|
|
1504
|
-
#line
|
1553
|
+
#line 1543 "parser.c"
|
1505
1554
|
{
|
1506
1555
|
cs = JSON_string_start;
|
1507
1556
|
}
|
1508
1557
|
|
1509
|
-
#line
|
1558
|
+
#line 563 "parser.rl"
|
1510
1559
|
json->memo = p;
|
1511
1560
|
|
1512
|
-
#line
|
1561
|
+
#line 1551 "parser.c"
|
1513
1562
|
{
|
1514
1563
|
if ( p == pe )
|
1515
1564
|
goto _test_eof;
|
@@ -1530,11 +1579,11 @@ case 2:
|
|
1530
1579
|
case 34: goto tr2;
|
1531
1580
|
case 92: goto st3;
|
1532
1581
|
}
|
1533
|
-
if ( 0 <= (*p) && (*p) <= 31 )
|
1582
|
+
if ( 0 <= (signed char)(*p) && (*p) <= 31 )
|
1534
1583
|
goto st0;
|
1535
1584
|
goto st2;
|
1536
1585
|
tr2:
|
1537
|
-
#line
|
1586
|
+
#line 528 "parser.rl"
|
1538
1587
|
{
|
1539
1588
|
*result = json_string_unescape(*result, json->memo + 1, p);
|
1540
1589
|
if (NIL_P(*result)) {
|
@@ -1545,14 +1594,14 @@ tr2:
|
|
1545
1594
|
{p = (( p + 1))-1;}
|
1546
1595
|
}
|
1547
1596
|
}
|
1548
|
-
#line
|
1597
|
+
#line 539 "parser.rl"
|
1549
1598
|
{ p--; {p++; cs = 8; goto _out;} }
|
1550
1599
|
goto st8;
|
1551
1600
|
st8:
|
1552
1601
|
if ( ++p == pe )
|
1553
1602
|
goto _test_eof8;
|
1554
1603
|
case 8:
|
1555
|
-
#line
|
1604
|
+
#line 1594 "parser.c"
|
1556
1605
|
goto st0;
|
1557
1606
|
st3:
|
1558
1607
|
if ( ++p == pe )
|
@@ -1560,7 +1609,7 @@ st3:
|
|
1560
1609
|
case 3:
|
1561
1610
|
if ( (*p) == 117 )
|
1562
1611
|
goto st4;
|
1563
|
-
if ( 0 <= (*p) && (*p) <= 31 )
|
1612
|
+
if ( 0 <= (signed char)(*p) && (*p) <= 31 )
|
1564
1613
|
goto st0;
|
1565
1614
|
goto st2;
|
1566
1615
|
st4:
|
@@ -1628,7 +1677,7 @@ case 7:
|
|
1628
1677
|
_out: {}
|
1629
1678
|
}
|
1630
1679
|
|
1631
|
-
#line
|
1680
|
+
#line 565 "parser.rl"
|
1632
1681
|
|
1633
1682
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1634
1683
|
VALUE klass;
|
@@ -1643,8 +1692,23 @@ case 7:
|
|
1643
1692
|
|
1644
1693
|
if (json->symbolize_names && json->parsing_name) {
|
1645
1694
|
*result = rb_str_intern(*result);
|
1646
|
-
} else {
|
1695
|
+
} else if (RB_TYPE_P(*result, T_STRING)) {
|
1696
|
+
# if STR_UMINUS_DEDUPE_FROZEN
|
1697
|
+
if (json->freeze) {
|
1698
|
+
// Starting from MRI 2.8 it is preferable to freeze the string
|
1699
|
+
// before deduplication so that it can be interned directly
|
1700
|
+
// otherwise it would be duplicated first which is wasteful.
|
1701
|
+
*result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
|
1702
|
+
}
|
1703
|
+
# elif STR_UMINUS_DEDUPE
|
1704
|
+
if (json->freeze) {
|
1705
|
+
// MRI 2.5 and older do not deduplicate strings that are already
|
1706
|
+
// frozen.
|
1707
|
+
*result = rb_funcall(*result, i_uminus, 0);
|
1708
|
+
}
|
1709
|
+
# else
|
1647
1710
|
rb_str_resize(*result, RSTRING_LEN(*result));
|
1711
|
+
# endif
|
1648
1712
|
}
|
1649
1713
|
if (cs >= JSON_string_first_final) {
|
1650
1714
|
return p + 1;
|
@@ -1752,6 +1816,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1752
1816
|
} else {
|
1753
1817
|
json->symbolize_names = 0;
|
1754
1818
|
}
|
1819
|
+
tmp = ID2SYM(i_freeze);
|
1820
|
+
if (option_given_p(opts, tmp)) {
|
1821
|
+
json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
|
1822
|
+
} else {
|
1823
|
+
json->freeze = 0;
|
1824
|
+
}
|
1755
1825
|
tmp = ID2SYM(i_create_additions);
|
1756
1826
|
if (option_given_p(opts, tmp)) {
|
1757
1827
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
@@ -1781,6 +1851,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1781
1851
|
} else {
|
1782
1852
|
json->array_class = Qnil;
|
1783
1853
|
}
|
1854
|
+
tmp = ID2SYM(i_decimal_class);
|
1855
|
+
if (option_given_p(opts, tmp)) {
|
1856
|
+
json->decimal_class = rb_hash_aref(opts, tmp);
|
1857
|
+
} else {
|
1858
|
+
json->decimal_class = Qnil;
|
1859
|
+
}
|
1784
1860
|
tmp = ID2SYM(i_match_string);
|
1785
1861
|
if (option_given_p(opts, tmp)) {
|
1786
1862
|
VALUE match_string = rb_hash_aref(opts, tmp);
|
@@ -1794,10 +1870,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1794
1870
|
} else {
|
1795
1871
|
json->max_nesting = 100;
|
1796
1872
|
json->allow_nan = 0;
|
1797
|
-
json->create_additions =
|
1873
|
+
json->create_additions = 0;
|
1798
1874
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1799
1875
|
json->object_class = Qnil;
|
1800
1876
|
json->array_class = Qnil;
|
1877
|
+
json->decimal_class = Qnil;
|
1801
1878
|
}
|
1802
1879
|
source = convert_encoding(StringValue(source));
|
1803
1880
|
StringValue(source);
|
@@ -1808,7 +1885,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1808
1885
|
}
|
1809
1886
|
|
1810
1887
|
|
1811
|
-
#line
|
1888
|
+
#line 1878 "parser.c"
|
1812
1889
|
enum {JSON_start = 1};
|
1813
1890
|
enum {JSON_first_final = 10};
|
1814
1891
|
enum {JSON_error = 0};
|
@@ -1816,7 +1893,7 @@ enum {JSON_error = 0};
|
|
1816
1893
|
enum {JSON_en_main = 1};
|
1817
1894
|
|
1818
1895
|
|
1819
|
-
#line
|
1896
|
+
#line 786 "parser.rl"
|
1820
1897
|
|
1821
1898
|
|
1822
1899
|
/*
|
@@ -1833,16 +1910,16 @@ static VALUE cParser_parse(VALUE self)
|
|
1833
1910
|
GET_PARSER;
|
1834
1911
|
|
1835
1912
|
|
1836
|
-
#line
|
1913
|
+
#line 1903 "parser.c"
|
1837
1914
|
{
|
1838
1915
|
cs = JSON_start;
|
1839
1916
|
}
|
1840
1917
|
|
1841
|
-
#line
|
1918
|
+
#line 802 "parser.rl"
|
1842
1919
|
p = json->source;
|
1843
1920
|
pe = p + json->len;
|
1844
1921
|
|
1845
|
-
#line
|
1922
|
+
#line 1912 "parser.c"
|
1846
1923
|
{
|
1847
1924
|
if ( p == pe )
|
1848
1925
|
goto _test_eof;
|
@@ -1876,7 +1953,7 @@ st0:
|
|
1876
1953
|
cs = 0;
|
1877
1954
|
goto _out;
|
1878
1955
|
tr2:
|
1879
|
-
#line
|
1956
|
+
#line 778 "parser.rl"
|
1880
1957
|
{
|
1881
1958
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
1882
1959
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -1886,7 +1963,7 @@ st10:
|
|
1886
1963
|
if ( ++p == pe )
|
1887
1964
|
goto _test_eof10;
|
1888
1965
|
case 10:
|
1889
|
-
#line
|
1966
|
+
#line 1956 "parser.c"
|
1890
1967
|
switch( (*p) ) {
|
1891
1968
|
case 13: goto st10;
|
1892
1969
|
case 32: goto st10;
|
@@ -1975,7 +2052,7 @@ case 9:
|
|
1975
2052
|
_out: {}
|
1976
2053
|
}
|
1977
2054
|
|
1978
|
-
#line
|
2055
|
+
#line 805 "parser.rl"
|
1979
2056
|
|
1980
2057
|
if (cs >= JSON_first_final && p == pe) {
|
1981
2058
|
return result;
|
@@ -1992,6 +2069,7 @@ static void JSON_mark(void *ptr)
|
|
1992
2069
|
rb_gc_mark_maybe(json->create_id);
|
1993
2070
|
rb_gc_mark_maybe(json->object_class);
|
1994
2071
|
rb_gc_mark_maybe(json->array_class);
|
2072
|
+
rb_gc_mark_maybe(json->decimal_class);
|
1995
2073
|
rb_gc_mark_maybe(json->match_string);
|
1996
2074
|
}
|
1997
2075
|
|
@@ -2041,20 +2119,32 @@ static VALUE cParser_source(VALUE self)
|
|
2041
2119
|
|
2042
2120
|
void Init_parser(void)
|
2043
2121
|
{
|
2122
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
2123
|
+
rb_ext_ractor_safe(true);
|
2124
|
+
#endif
|
2125
|
+
|
2126
|
+
#undef rb_intern
|
2044
2127
|
rb_require("json/common");
|
2045
2128
|
mJSON = rb_define_module("JSON");
|
2046
2129
|
mExt = rb_define_module_under(mJSON, "Ext");
|
2047
2130
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
2048
2131
|
eParserError = rb_path2class("JSON::ParserError");
|
2049
2132
|
eNestingError = rb_path2class("JSON::NestingError");
|
2133
|
+
rb_gc_register_mark_object(eParserError);
|
2134
|
+
rb_gc_register_mark_object(eNestingError);
|
2050
2135
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
2051
2136
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
2052
2137
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2053
2138
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2054
2139
|
|
2055
2140
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2141
|
+
rb_gc_register_mark_object(CNaN);
|
2142
|
+
|
2056
2143
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
2144
|
+
rb_gc_register_mark_object(CInfinity);
|
2145
|
+
|
2057
2146
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2147
|
+
rb_gc_register_mark_object(CMinusInfinity);
|
2058
2148
|
|
2059
2149
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2060
2150
|
i_json_create = rb_intern("json_create");
|
@@ -2066,6 +2156,7 @@ void Init_parser(void)
|
|
2066
2156
|
i_symbolize_names = rb_intern("symbolize_names");
|
2067
2157
|
i_object_class = rb_intern("object_class");
|
2068
2158
|
i_array_class = rb_intern("array_class");
|
2159
|
+
i_decimal_class = rb_intern("decimal_class");
|
2069
2160
|
i_match = rb_intern("match");
|
2070
2161
|
i_match_string = rb_intern("match_string");
|
2071
2162
|
i_key_p = rb_intern("key?");
|
@@ -2073,6 +2164,10 @@ void Init_parser(void)
|
|
2073
2164
|
i_aset = rb_intern("[]=");
|
2074
2165
|
i_aref = rb_intern("[]");
|
2075
2166
|
i_leftshift = rb_intern("<<");
|
2167
|
+
i_new = rb_intern("new");
|
2168
|
+
i_try_convert = rb_intern("try_convert");
|
2169
|
+
i_freeze = rb_intern("freeze");
|
2170
|
+
i_uminus = rb_intern("-@");
|
2076
2171
|
}
|
2077
2172
|
|
2078
2173
|
/*
|