json 2.2.0 → 2.5.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.
- checksums.yaml +4 -4
- data/CHANGES.md +51 -0
- data/LICENSE +56 -0
- data/README.md +17 -1
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +222 -48
- data/ext/json/ext/generator/generator.h +5 -2
- data/ext/json/ext/parser/extconf.rb +25 -0
- data/ext/json/ext/parser/parser.c +150 -102
- data/ext/json/ext/parser/parser.h +1 -0
- data/ext/json/ext/parser/parser.rl +80 -32
- data/ext/json/extconf.rb +1 -0
- data/json.gemspec +0 -0
- data/lib/json.rb +549 -29
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +2 -3
- data/lib/json/add/rational.rb +2 -3
- data/lib/json/add/regexp.rb +2 -2
- data/lib/json/common.rb +370 -125
- data/lib/json/pure/generator.rb +31 -10
- data/lib/json/pure/parser.rb +31 -5
- data/lib/json/version.rb +1 -1
- 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 +0 -4
- data/tests/json_common_interface_test.rb +47 -4
- data/tests/json_fixtures_test.rb +9 -1
- data/tests/json_generator_test.rb +30 -8
- data/tests/json_parser_test.rb +39 -14
- 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 -3
- metadata +30 -40
- data/.gitignore +0 -17
- data/.travis.yml +0 -23
- data/README-json-jruby.md +0 -33
- data/Rakefile +0 -408
- 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 -2362
- data/java/src/json/ext/Parser.rl +0 -893
- 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
@@ -49,8 +49,8 @@ static const UTF32 halfMask = 0x3FFUL;
|
|
49
49
|
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length);
|
50
50
|
static void unicode_escape(char *buf, UTF16 character);
|
51
51
|
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
|
52
|
-
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
|
53
|
-
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
|
52
|
+
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash);
|
53
|
+
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash);
|
54
54
|
static char *fstrndup(const char *ptr, unsigned long len);
|
55
55
|
|
56
56
|
/* ruby api and some helpers */
|
@@ -72,6 +72,7 @@ typedef struct JSON_Generator_StateStruct {
|
|
72
72
|
long max_nesting;
|
73
73
|
char allow_nan;
|
74
74
|
char ascii_only;
|
75
|
+
char escape_slash;
|
75
76
|
long depth;
|
76
77
|
long buffer_initial_length;
|
77
78
|
} JSON_Generator_State;
|
@@ -150,6 +151,8 @@ static VALUE cState_allow_nan_p(VALUE self);
|
|
150
151
|
static VALUE cState_ascii_only_p(VALUE self);
|
151
152
|
static VALUE cState_depth(VALUE self);
|
152
153
|
static VALUE cState_depth_set(VALUE self, VALUE depth);
|
154
|
+
static VALUE cState_escape_slash(VALUE self);
|
155
|
+
static VALUE cState_escape_slash_set(VALUE self, VALUE depth);
|
153
156
|
static FBuffer *cState_prepare_buffer(VALUE self);
|
154
157
|
#ifndef ZALLOC
|
155
158
|
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
|
@@ -3,4 +3,29 @@ require 'mkmf'
|
|
3
3
|
|
4
4
|
have_func("rb_enc_raise", "ruby.h")
|
5
5
|
|
6
|
+
# checking if String#-@ (str_uminus) dedupes... '
|
7
|
+
begin
|
8
|
+
a = -(%w(t e s t).join)
|
9
|
+
b = -(%w(t e s t).join)
|
10
|
+
if a.equal?(b)
|
11
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
12
|
+
else
|
13
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
14
|
+
end
|
15
|
+
rescue NoMethodError
|
16
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
17
|
+
end
|
18
|
+
|
19
|
+
# checking if String#-@ (str_uminus) directly interns frozen strings... '
|
20
|
+
begin
|
21
|
+
s = rand.to_s.freeze
|
22
|
+
if (-s).equal?(s) && (-s.dup).equal?(s)
|
23
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
|
24
|
+
else
|
25
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
|
26
|
+
end
|
27
|
+
rescue NoMethodError
|
28
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
|
29
|
+
end
|
30
|
+
|
6
31
|
create_makefile 'json/ext/parser'
|
@@ -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;
|
@@ -91,13 +91,12 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
91
91
|
|
92
92
|
static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
93
93
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
94
|
-
static VALUE cBigDecimal = Qundef;
|
95
94
|
|
96
95
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
97
96
|
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
|
98
97
|
i_object_class, i_array_class, i_decimal_class, i_key_p,
|
99
98
|
i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
|
100
|
-
i_leftshift, i_new,
|
99
|
+
i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
|
101
100
|
|
102
101
|
|
103
102
|
#line 126 "parser.rl"
|
@@ -112,7 +111,7 @@ enum {JSON_object_error = 0};
|
|
112
111
|
enum {JSON_object_en_main = 1};
|
113
112
|
|
114
113
|
|
115
|
-
#line
|
114
|
+
#line 168 "parser.rl"
|
116
115
|
|
117
116
|
|
118
117
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -133,7 +132,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
133
132
|
cs = JSON_object_start;
|
134
133
|
}
|
135
134
|
|
136
|
-
#line
|
135
|
+
#line 183 "parser.rl"
|
137
136
|
|
138
137
|
#line 139 "parser.c"
|
139
138
|
{
|
@@ -163,7 +162,7 @@ case 2:
|
|
163
162
|
goto st2;
|
164
163
|
goto st0;
|
165
164
|
tr2:
|
166
|
-
#line
|
165
|
+
#line 150 "parser.rl"
|
167
166
|
{
|
168
167
|
char *np;
|
169
168
|
json->parsing_name = 1;
|
@@ -251,6 +250,7 @@ tr11:
|
|
251
250
|
p--; {p++; cs = 9; goto _out;}
|
252
251
|
} else {
|
253
252
|
if (NIL_P(json->object_class)) {
|
253
|
+
OBJ_FREEZE(last_name);
|
254
254
|
rb_hash_aset(*result, last_name, v);
|
255
255
|
} else {
|
256
256
|
rb_funcall(*result, i_aset, 2, last_name, v);
|
@@ -263,7 +263,7 @@ st9:
|
|
263
263
|
if ( ++p == pe )
|
264
264
|
goto _test_eof9;
|
265
265
|
case 9:
|
266
|
-
#line
|
266
|
+
#line 268 "parser.c"
|
267
267
|
switch( (*p) ) {
|
268
268
|
case 13: goto st9;
|
269
269
|
case 32: goto st9;
|
@@ -352,14 +352,14 @@ case 18:
|
|
352
352
|
goto st9;
|
353
353
|
goto st18;
|
354
354
|
tr4:
|
355
|
-
#line
|
355
|
+
#line 158 "parser.rl"
|
356
356
|
{ p--; {p++; cs = 27; goto _out;} }
|
357
357
|
goto st27;
|
358
358
|
st27:
|
359
359
|
if ( ++p == pe )
|
360
360
|
goto _test_eof27;
|
361
361
|
case 27:
|
362
|
-
#line
|
362
|
+
#line 364 "parser.c"
|
363
363
|
goto st0;
|
364
364
|
st19:
|
365
365
|
if ( ++p == pe )
|
@@ -457,7 +457,7 @@ case 26:
|
|
457
457
|
_out: {}
|
458
458
|
}
|
459
459
|
|
460
|
-
#line
|
460
|
+
#line 184 "parser.rl"
|
461
461
|
|
462
462
|
if (cs >= JSON_object_first_final) {
|
463
463
|
if (json->create_additions) {
|
@@ -482,7 +482,7 @@ case 26:
|
|
482
482
|
|
483
483
|
|
484
484
|
|
485
|
-
#line
|
485
|
+
#line 487 "parser.c"
|
486
486
|
enum {JSON_value_start = 1};
|
487
487
|
enum {JSON_value_first_final = 29};
|
488
488
|
enum {JSON_value_error = 0};
|
@@ -490,7 +490,7 @@ enum {JSON_value_error = 0};
|
|
490
490
|
enum {JSON_value_en_main = 1};
|
491
491
|
|
492
492
|
|
493
|
-
#line
|
493
|
+
#line 284 "parser.rl"
|
494
494
|
|
495
495
|
|
496
496
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -498,14 +498,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
498
498
|
int cs = EVIL;
|
499
499
|
|
500
500
|
|
501
|
-
#line
|
501
|
+
#line 503 "parser.c"
|
502
502
|
{
|
503
503
|
cs = JSON_value_start;
|
504
504
|
}
|
505
505
|
|
506
|
-
#line
|
506
|
+
#line 291 "parser.rl"
|
507
507
|
|
508
|
-
#line
|
508
|
+
#line 510 "parser.c"
|
509
509
|
{
|
510
510
|
if ( p == pe )
|
511
511
|
goto _test_eof;
|
@@ -539,14 +539,14 @@ st0:
|
|
539
539
|
cs = 0;
|
540
540
|
goto _out;
|
541
541
|
tr2:
|
542
|
-
#line
|
542
|
+
#line 236 "parser.rl"
|
543
543
|
{
|
544
544
|
char *np = JSON_parse_string(json, p, pe, result);
|
545
545
|
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
|
546
546
|
}
|
547
547
|
goto st29;
|
548
548
|
tr3:
|
549
|
-
#line
|
549
|
+
#line 241 "parser.rl"
|
550
550
|
{
|
551
551
|
char *np;
|
552
552
|
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -566,7 +566,7 @@ tr3:
|
|
566
566
|
}
|
567
567
|
goto st29;
|
568
568
|
tr7:
|
569
|
-
#line
|
569
|
+
#line 259 "parser.rl"
|
570
570
|
{
|
571
571
|
char *np;
|
572
572
|
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
|
@@ -574,7 +574,7 @@ tr7:
|
|
574
574
|
}
|
575
575
|
goto st29;
|
576
576
|
tr11:
|
577
|
-
#line
|
577
|
+
#line 265 "parser.rl"
|
578
578
|
{
|
579
579
|
char *np;
|
580
580
|
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
|
@@ -582,7 +582,7 @@ tr11:
|
|
582
582
|
}
|
583
583
|
goto st29;
|
584
584
|
tr25:
|
585
|
-
#line
|
585
|
+
#line 229 "parser.rl"
|
586
586
|
{
|
587
587
|
if (json->allow_nan) {
|
588
588
|
*result = CInfinity;
|
@@ -592,7 +592,7 @@ tr25:
|
|
592
592
|
}
|
593
593
|
goto st29;
|
594
594
|
tr27:
|
595
|
-
#line
|
595
|
+
#line 222 "parser.rl"
|
596
596
|
{
|
597
597
|
if (json->allow_nan) {
|
598
598
|
*result = CNaN;
|
@@ -602,19 +602,19 @@ tr27:
|
|
602
602
|
}
|
603
603
|
goto st29;
|
604
604
|
tr31:
|
605
|
-
#line
|
605
|
+
#line 216 "parser.rl"
|
606
606
|
{
|
607
607
|
*result = Qfalse;
|
608
608
|
}
|
609
609
|
goto st29;
|
610
610
|
tr34:
|
611
|
-
#line
|
611
|
+
#line 213 "parser.rl"
|
612
612
|
{
|
613
613
|
*result = Qnil;
|
614
614
|
}
|
615
615
|
goto st29;
|
616
616
|
tr37:
|
617
|
-
#line
|
617
|
+
#line 219 "parser.rl"
|
618
618
|
{
|
619
619
|
*result = Qtrue;
|
620
620
|
}
|
@@ -623,9 +623,9 @@ st29:
|
|
623
623
|
if ( ++p == pe )
|
624
624
|
goto _test_eof29;
|
625
625
|
case 29:
|
626
|
-
#line
|
626
|
+
#line 271 "parser.rl"
|
627
627
|
{ p--; {p++; cs = 29; goto _out;} }
|
628
|
-
#line
|
628
|
+
#line 630 "parser.c"
|
629
629
|
switch( (*p) ) {
|
630
630
|
case 13: goto st29;
|
631
631
|
case 32: goto st29;
|
@@ -866,7 +866,11 @@ case 28:
|
|
866
866
|
_out: {}
|
867
867
|
}
|
868
868
|
|
869
|
-
#line
|
869
|
+
#line 292 "parser.rl"
|
870
|
+
|
871
|
+
if (json->freeze) {
|
872
|
+
OBJ_FREEZE(*result);
|
873
|
+
}
|
870
874
|
|
871
875
|
if (cs >= JSON_value_first_final) {
|
872
876
|
return p;
|
@@ -876,7 +880,7 @@ case 28:
|
|
876
880
|
}
|
877
881
|
|
878
882
|
|
879
|
-
#line
|
883
|
+
#line 885 "parser.c"
|
880
884
|
enum {JSON_integer_start = 1};
|
881
885
|
enum {JSON_integer_first_final = 3};
|
882
886
|
enum {JSON_integer_error = 0};
|
@@ -884,7 +888,7 @@ enum {JSON_integer_error = 0};
|
|
884
888
|
enum {JSON_integer_en_main = 1};
|
885
889
|
|
886
890
|
|
887
|
-
#line
|
891
|
+
#line 312 "parser.rl"
|
888
892
|
|
889
893
|
|
890
894
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -892,15 +896,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
892
896
|
int cs = EVIL;
|
893
897
|
|
894
898
|
|
895
|
-
#line
|
899
|
+
#line 901 "parser.c"
|
896
900
|
{
|
897
901
|
cs = JSON_integer_start;
|
898
902
|
}
|
899
903
|
|
900
|
-
#line
|
904
|
+
#line 319 "parser.rl"
|
901
905
|
json->memo = p;
|
902
906
|
|
903
|
-
#line
|
907
|
+
#line 909 "parser.c"
|
904
908
|
{
|
905
909
|
if ( p == pe )
|
906
910
|
goto _test_eof;
|
@@ -934,14 +938,14 @@ case 3:
|
|
934
938
|
goto st0;
|
935
939
|
goto tr4;
|
936
940
|
tr4:
|
937
|
-
#line
|
941
|
+
#line 309 "parser.rl"
|
938
942
|
{ p--; {p++; cs = 4; goto _out;} }
|
939
943
|
goto st4;
|
940
944
|
st4:
|
941
945
|
if ( ++p == pe )
|
942
946
|
goto _test_eof4;
|
943
947
|
case 4:
|
944
|
-
#line
|
948
|
+
#line 950 "parser.c"
|
945
949
|
goto st0;
|
946
950
|
st5:
|
947
951
|
if ( ++p == pe )
|
@@ -960,7 +964,7 @@ case 5:
|
|
960
964
|
_out: {}
|
961
965
|
}
|
962
966
|
|
963
|
-
#line
|
967
|
+
#line 321 "parser.rl"
|
964
968
|
|
965
969
|
if (cs >= JSON_integer_first_final) {
|
966
970
|
long len = p - json->memo;
|
@@ -975,7 +979,7 @@ case 5:
|
|
975
979
|
}
|
976
980
|
|
977
981
|
|
978
|
-
#line
|
982
|
+
#line 984 "parser.c"
|
979
983
|
enum {JSON_float_start = 1};
|
980
984
|
enum {JSON_float_first_final = 8};
|
981
985
|
enum {JSON_float_error = 0};
|
@@ -983,36 +987,23 @@ enum {JSON_float_error = 0};
|
|
983
987
|
enum {JSON_float_en_main = 1};
|
984
988
|
|
985
989
|
|
986
|
-
#line
|
987
|
-
|
990
|
+
#line 346 "parser.rl"
|
988
991
|
|
989
|
-
static int is_bigdecimal_class(VALUE obj)
|
990
|
-
{
|
991
|
-
if (cBigDecimal == Qundef) {
|
992
|
-
if (rb_const_defined(rb_cObject, i_BigDecimal)) {
|
993
|
-
cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
|
994
|
-
}
|
995
|
-
else {
|
996
|
-
return 0;
|
997
|
-
}
|
998
|
-
}
|
999
|
-
return obj == cBigDecimal;
|
1000
|
-
}
|
1001
992
|
|
1002
993
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
1003
994
|
{
|
1004
995
|
int cs = EVIL;
|
1005
996
|
|
1006
997
|
|
1007
|
-
#line
|
998
|
+
#line 1013 "parser.c"
|
1008
999
|
{
|
1009
1000
|
cs = JSON_float_start;
|
1010
1001
|
}
|
1011
1002
|
|
1012
|
-
#line
|
1003
|
+
#line 366 "parser.rl"
|
1013
1004
|
json->memo = p;
|
1014
1005
|
|
1015
|
-
#line
|
1006
|
+
#line 1021 "parser.c"
|
1016
1007
|
{
|
1017
1008
|
if ( p == pe )
|
1018
1009
|
goto _test_eof;
|
@@ -1070,14 +1061,14 @@ case 8:
|
|
1070
1061
|
goto st0;
|
1071
1062
|
goto tr9;
|
1072
1063
|
tr9:
|
1073
|
-
#line
|
1064
|
+
#line 340 "parser.rl"
|
1074
1065
|
{ p--; {p++; cs = 9; goto _out;} }
|
1075
1066
|
goto st9;
|
1076
1067
|
st9:
|
1077
1068
|
if ( ++p == pe )
|
1078
1069
|
goto _test_eof9;
|
1079
1070
|
case 9:
|
1080
|
-
#line
|
1071
|
+
#line 1086 "parser.c"
|
1081
1072
|
goto st0;
|
1082
1073
|
st5:
|
1083
1074
|
if ( ++p == pe )
|
@@ -1138,24 +1129,49 @@ case 7:
|
|
1138
1129
|
_out: {}
|
1139
1130
|
}
|
1140
1131
|
|
1141
|
-
#line
|
1132
|
+
#line 368 "parser.rl"
|
1142
1133
|
|
1143
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
|
+
|
1144
1163
|
long len = p - json->memo;
|
1145
1164
|
fbuffer_clear(json->fbuffer);
|
1146
1165
|
fbuffer_append(json->fbuffer, json->memo, len);
|
1147
1166
|
fbuffer_append_char(json->fbuffer, '\0');
|
1148
|
-
|
1149
|
-
|
1167
|
+
|
1168
|
+
if (method_id) {
|
1169
|
+
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1170
|
+
*result = rb_funcallv(mod, method_id, 1, &text);
|
1150
1171
|
} else {
|
1151
|
-
|
1152
|
-
text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
|
1153
|
-
if (is_bigdecimal_class(json->decimal_class)) {
|
1154
|
-
*result = rb_funcall(Qnil, i_BigDecimal, 1, text);
|
1155
|
-
} else {
|
1156
|
-
*result = rb_funcall(json->decimal_class, i_new, 1, text);
|
1157
|
-
}
|
1172
|
+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
|
1158
1173
|
}
|
1174
|
+
|
1159
1175
|
return p + 1;
|
1160
1176
|
} else {
|
1161
1177
|
return NULL;
|
@@ -1164,7 +1180,7 @@ case 7:
|
|
1164
1180
|
|
1165
1181
|
|
1166
1182
|
|
1167
|
-
#line
|
1183
|
+
#line 1173 "parser.c"
|
1168
1184
|
enum {JSON_array_start = 1};
|
1169
1185
|
enum {JSON_array_first_final = 17};
|
1170
1186
|
enum {JSON_array_error = 0};
|
@@ -1172,7 +1188,7 @@ enum {JSON_array_error = 0};
|
|
1172
1188
|
enum {JSON_array_en_main = 1};
|
1173
1189
|
|
1174
1190
|
|
1175
|
-
#line
|
1191
|
+
#line 421 "parser.rl"
|
1176
1192
|
|
1177
1193
|
|
1178
1194
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
|
@@ -1186,14 +1202,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1186
1202
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1187
1203
|
|
1188
1204
|
|
1189
|
-
#line
|
1205
|
+
#line 1195 "parser.c"
|
1190
1206
|
{
|
1191
1207
|
cs = JSON_array_start;
|
1192
1208
|
}
|
1193
1209
|
|
1194
|
-
#line
|
1210
|
+
#line 434 "parser.rl"
|
1195
1211
|
|
1196
|
-
#line
|
1212
|
+
#line 1202 "parser.c"
|
1197
1213
|
{
|
1198
1214
|
if ( p == pe )
|
1199
1215
|
goto _test_eof;
|
@@ -1232,7 +1248,7 @@ case 2:
|
|
1232
1248
|
goto st2;
|
1233
1249
|
goto st0;
|
1234
1250
|
tr2:
|
1235
|
-
#line
|
1251
|
+
#line 398 "parser.rl"
|
1236
1252
|
{
|
1237
1253
|
VALUE v = Qnil;
|
1238
1254
|
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
|
@@ -1252,7 +1268,7 @@ st3:
|
|
1252
1268
|
if ( ++p == pe )
|
1253
1269
|
goto _test_eof3;
|
1254
1270
|
case 3:
|
1255
|
-
#line
|
1271
|
+
#line 1261 "parser.c"
|
1256
1272
|
switch( (*p) ) {
|
1257
1273
|
case 13: goto st3;
|
1258
1274
|
case 32: goto st3;
|
@@ -1352,14 +1368,14 @@ case 12:
|
|
1352
1368
|
goto st3;
|
1353
1369
|
goto st12;
|
1354
1370
|
tr4:
|
1355
|
-
#line
|
1371
|
+
#line 413 "parser.rl"
|
1356
1372
|
{ p--; {p++; cs = 17; goto _out;} }
|
1357
1373
|
goto st17;
|
1358
1374
|
st17:
|
1359
1375
|
if ( ++p == pe )
|
1360
1376
|
goto _test_eof17;
|
1361
1377
|
case 17:
|
1362
|
-
#line
|
1378
|
+
#line 1368 "parser.c"
|
1363
1379
|
goto st0;
|
1364
1380
|
st13:
|
1365
1381
|
if ( ++p == pe )
|
@@ -1415,7 +1431,7 @@ case 16:
|
|
1415
1431
|
_out: {}
|
1416
1432
|
}
|
1417
1433
|
|
1418
|
-
#line
|
1434
|
+
#line 435 "parser.rl"
|
1419
1435
|
|
1420
1436
|
if(cs >= JSON_array_first_final) {
|
1421
1437
|
return p + 1;
|
@@ -1504,7 +1520,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
|
|
1504
1520
|
}
|
1505
1521
|
|
1506
1522
|
|
1507
|
-
#line
|
1523
|
+
#line 1513 "parser.c"
|
1508
1524
|
enum {JSON_string_start = 1};
|
1509
1525
|
enum {JSON_string_first_final = 8};
|
1510
1526
|
enum {JSON_string_error = 0};
|
@@ -1512,7 +1528,7 @@ enum {JSON_string_error = 0};
|
|
1512
1528
|
enum {JSON_string_en_main = 1};
|
1513
1529
|
|
1514
1530
|
|
1515
|
-
#line
|
1531
|
+
#line 542 "parser.rl"
|
1516
1532
|
|
1517
1533
|
|
1518
1534
|
static int
|
@@ -1534,15 +1550,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1534
1550
|
|
1535
1551
|
*result = rb_str_buf_new(0);
|
1536
1552
|
|
1537
|
-
#line
|
1553
|
+
#line 1543 "parser.c"
|
1538
1554
|
{
|
1539
1555
|
cs = JSON_string_start;
|
1540
1556
|
}
|
1541
1557
|
|
1542
|
-
#line
|
1558
|
+
#line 563 "parser.rl"
|
1543
1559
|
json->memo = p;
|
1544
1560
|
|
1545
|
-
#line
|
1561
|
+
#line 1551 "parser.c"
|
1546
1562
|
{
|
1547
1563
|
if ( p == pe )
|
1548
1564
|
goto _test_eof;
|
@@ -1563,11 +1579,11 @@ case 2:
|
|
1563
1579
|
case 34: goto tr2;
|
1564
1580
|
case 92: goto st3;
|
1565
1581
|
}
|
1566
|
-
if ( 0 <= (*p) && (*p) <= 31 )
|
1582
|
+
if ( 0 <= (signed char)(*p) && (*p) <= 31 )
|
1567
1583
|
goto st0;
|
1568
1584
|
goto st2;
|
1569
1585
|
tr2:
|
1570
|
-
#line
|
1586
|
+
#line 528 "parser.rl"
|
1571
1587
|
{
|
1572
1588
|
*result = json_string_unescape(*result, json->memo + 1, p);
|
1573
1589
|
if (NIL_P(*result)) {
|
@@ -1578,14 +1594,14 @@ tr2:
|
|
1578
1594
|
{p = (( p + 1))-1;}
|
1579
1595
|
}
|
1580
1596
|
}
|
1581
|
-
#line
|
1597
|
+
#line 539 "parser.rl"
|
1582
1598
|
{ p--; {p++; cs = 8; goto _out;} }
|
1583
1599
|
goto st8;
|
1584
1600
|
st8:
|
1585
1601
|
if ( ++p == pe )
|
1586
1602
|
goto _test_eof8;
|
1587
1603
|
case 8:
|
1588
|
-
#line
|
1604
|
+
#line 1594 "parser.c"
|
1589
1605
|
goto st0;
|
1590
1606
|
st3:
|
1591
1607
|
if ( ++p == pe )
|
@@ -1593,7 +1609,7 @@ st3:
|
|
1593
1609
|
case 3:
|
1594
1610
|
if ( (*p) == 117 )
|
1595
1611
|
goto st4;
|
1596
|
-
if ( 0 <= (*p) && (*p) <= 31 )
|
1612
|
+
if ( 0 <= (signed char)(*p) && (*p) <= 31 )
|
1597
1613
|
goto st0;
|
1598
1614
|
goto st2;
|
1599
1615
|
st4:
|
@@ -1661,7 +1677,7 @@ case 7:
|
|
1661
1677
|
_out: {}
|
1662
1678
|
}
|
1663
1679
|
|
1664
|
-
#line
|
1680
|
+
#line 565 "parser.rl"
|
1665
1681
|
|
1666
1682
|
if (json->create_additions && RTEST(match_string = json->match_string)) {
|
1667
1683
|
VALUE klass;
|
@@ -1676,10 +1692,23 @@ case 7:
|
|
1676
1692
|
|
1677
1693
|
if (json->symbolize_names && json->parsing_name) {
|
1678
1694
|
*result = rb_str_intern(*result);
|
1679
|
-
} else {
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
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
|
1710
|
+
rb_str_resize(*result, RSTRING_LEN(*result));
|
1711
|
+
# endif
|
1683
1712
|
}
|
1684
1713
|
if (cs >= JSON_string_first_final) {
|
1685
1714
|
return p + 1;
|
@@ -1787,6 +1816,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1787
1816
|
} else {
|
1788
1817
|
json->symbolize_names = 0;
|
1789
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
|
+
}
|
1790
1825
|
tmp = ID2SYM(i_create_additions);
|
1791
1826
|
if (option_given_p(opts, tmp)) {
|
1792
1827
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
@@ -1835,7 +1870,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1835
1870
|
} else {
|
1836
1871
|
json->max_nesting = 100;
|
1837
1872
|
json->allow_nan = 0;
|
1838
|
-
json->create_additions =
|
1873
|
+
json->create_additions = 0;
|
1839
1874
|
json->create_id = rb_funcall(mJSON, i_create_id, 0);
|
1840
1875
|
json->object_class = Qnil;
|
1841
1876
|
json->array_class = Qnil;
|
@@ -1850,7 +1885,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1850
1885
|
}
|
1851
1886
|
|
1852
1887
|
|
1853
|
-
#line
|
1888
|
+
#line 1878 "parser.c"
|
1854
1889
|
enum {JSON_start = 1};
|
1855
1890
|
enum {JSON_first_final = 10};
|
1856
1891
|
enum {JSON_error = 0};
|
@@ -1858,7 +1893,7 @@ enum {JSON_error = 0};
|
|
1858
1893
|
enum {JSON_en_main = 1};
|
1859
1894
|
|
1860
1895
|
|
1861
|
-
#line
|
1896
|
+
#line 786 "parser.rl"
|
1862
1897
|
|
1863
1898
|
|
1864
1899
|
/*
|
@@ -1875,16 +1910,16 @@ static VALUE cParser_parse(VALUE self)
|
|
1875
1910
|
GET_PARSER;
|
1876
1911
|
|
1877
1912
|
|
1878
|
-
#line
|
1913
|
+
#line 1903 "parser.c"
|
1879
1914
|
{
|
1880
1915
|
cs = JSON_start;
|
1881
1916
|
}
|
1882
1917
|
|
1883
|
-
#line
|
1918
|
+
#line 802 "parser.rl"
|
1884
1919
|
p = json->source;
|
1885
1920
|
pe = p + json->len;
|
1886
1921
|
|
1887
|
-
#line
|
1922
|
+
#line 1912 "parser.c"
|
1888
1923
|
{
|
1889
1924
|
if ( p == pe )
|
1890
1925
|
goto _test_eof;
|
@@ -1918,7 +1953,7 @@ st0:
|
|
1918
1953
|
cs = 0;
|
1919
1954
|
goto _out;
|
1920
1955
|
tr2:
|
1921
|
-
#line
|
1956
|
+
#line 778 "parser.rl"
|
1922
1957
|
{
|
1923
1958
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
1924
1959
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
@@ -1928,7 +1963,7 @@ st10:
|
|
1928
1963
|
if ( ++p == pe )
|
1929
1964
|
goto _test_eof10;
|
1930
1965
|
case 10:
|
1931
|
-
#line
|
1966
|
+
#line 1956 "parser.c"
|
1932
1967
|
switch( (*p) ) {
|
1933
1968
|
case 13: goto st10;
|
1934
1969
|
case 32: goto st10;
|
@@ -2017,7 +2052,7 @@ case 9:
|
|
2017
2052
|
_out: {}
|
2018
2053
|
}
|
2019
2054
|
|
2020
|
-
#line
|
2055
|
+
#line 805 "parser.rl"
|
2021
2056
|
|
2022
2057
|
if (cs >= JSON_first_final && p == pe) {
|
2023
2058
|
return result;
|
@@ -2084,6 +2119,10 @@ static VALUE cParser_source(VALUE self)
|
|
2084
2119
|
|
2085
2120
|
void Init_parser(void)
|
2086
2121
|
{
|
2122
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
2123
|
+
rb_ext_ractor_safe(true);
|
2124
|
+
#endif
|
2125
|
+
|
2087
2126
|
#undef rb_intern
|
2088
2127
|
rb_require("json/common");
|
2089
2128
|
mJSON = rb_define_module("JSON");
|
@@ -2091,14 +2130,21 @@ void Init_parser(void)
|
|
2091
2130
|
cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
|
2092
2131
|
eParserError = rb_path2class("JSON::ParserError");
|
2093
2132
|
eNestingError = rb_path2class("JSON::NestingError");
|
2133
|
+
rb_gc_register_mark_object(eParserError);
|
2134
|
+
rb_gc_register_mark_object(eNestingError);
|
2094
2135
|
rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
|
2095
2136
|
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
2096
2137
|
rb_define_method(cParser, "parse", cParser_parse, 0);
|
2097
2138
|
rb_define_method(cParser, "source", cParser_source, 0);
|
2098
2139
|
|
2099
2140
|
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
2141
|
+
rb_gc_register_mark_object(CNaN);
|
2142
|
+
|
2100
2143
|
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
2144
|
+
rb_gc_register_mark_object(CInfinity);
|
2145
|
+
|
2101
2146
|
CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
|
2147
|
+
rb_gc_register_mark_object(CMinusInfinity);
|
2102
2148
|
|
2103
2149
|
i_json_creatable_p = rb_intern("json_creatable?");
|
2104
2150
|
i_json_create = rb_intern("json_create");
|
@@ -2119,7 +2165,9 @@ void Init_parser(void)
|
|
2119
2165
|
i_aref = rb_intern("[]");
|
2120
2166
|
i_leftshift = rb_intern("<<");
|
2121
2167
|
i_new = rb_intern("new");
|
2122
|
-
|
2168
|
+
i_try_convert = rb_intern("try_convert");
|
2169
|
+
i_freeze = rb_intern("freeze");
|
2170
|
+
i_uminus = rb_intern("-@");
|
2123
2171
|
}
|
2124
2172
|
|
2125
2173
|
/*
|