json 2.3.0 → 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 +4 -4
- data/CHANGES.md +55 -0
- data/README.md +16 -0
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +131 -12
- 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 +138 -95
- data/ext/json/ext/parser/parser.h +1 -0
- data/ext/json/ext/parser/parser.rl +68 -25
- data/ext/json/extconf.rb +1 -0
- data/json.gemspec +0 -0
- data/lib/json.rb +549 -29
- data/lib/json/add/complex.rb +0 -1
- data/lib/json/add/rational.rb +0 -1
- data/lib/json/common.rb +370 -123
- data/lib/json/pure/generator.rb +29 -9
- data/lib/json/pure/parser.rb +22 -4
- 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 +43 -0
- data/tests/json_fixtures_test.rb +9 -1
- data/tests/json_generator_test.rb +16 -38
- data/tests/json_parser_test.rb +25 -0
- 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 +29 -40
- data/.gitignore +0 -18
- data/.travis.yml +0 -24
- data/README-json-jruby.md +0 -33
- data/Rakefile +0 -413
- 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 -466
- 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 -37
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ba367cf703870f72ec5de7af43e713095df4b9c88cb0ae12a4c10455052383a
|
|
4
|
+
data.tar.gz: 622fc0230b9a26ddde47fb3e81c2cf2f0143c22cbfd2429019db1a0f9eef5aaa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1cab7c9113f03333b720a039fd065d5dd376ab3b4dda1630ccf316ee72121ed4a8abfc06a576be524ce7a86b78e9af917b507fbe95411efef11a563da95295c4
|
|
7
|
+
data.tar.gz: 68b7cec95107a831286fc3ff36971cd9cc0efbc29157bc0df95a16238b5594214ffca0d417f2dd9011f9e26bf4e163e01e179cbf06f8c053df68c4d60f2416cc
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2020-12-22 (2.5.1)
|
|
4
|
+
|
|
5
|
+
* Restore the compatibility for constants of JSON class.
|
|
6
|
+
|
|
7
|
+
## 2020-12-22 (2.5.0)
|
|
8
|
+
|
|
9
|
+
* Ready to Ractor-safe at Ruby 3.0.
|
|
10
|
+
|
|
11
|
+
## 2020-12-17 (2.4.1)
|
|
12
|
+
|
|
13
|
+
* Restore version.rb with 2.4.1
|
|
14
|
+
|
|
15
|
+
## 2020-12-15 (2.4.0)
|
|
16
|
+
|
|
17
|
+
* Implement a freeze: parser option #447
|
|
18
|
+
* Fix an issue with generate_pretty and empty objects in the Ruby and Java implementations #449
|
|
19
|
+
* Fix JSON.load_file doc #448
|
|
20
|
+
* Fix pure parser with unclosed arrays / objects #425
|
|
21
|
+
* bundle the LICENSE file in the gem #444
|
|
22
|
+
* Add an option to escape forward slash character #405
|
|
23
|
+
* RDoc for JSON #439 #446 #442 #434 #433 #430
|
|
24
|
+
|
|
25
|
+
## 2020-06-30 (2.3.1)
|
|
26
|
+
|
|
27
|
+
* Spelling and grammar fixes for comments. Pull request #191 by Josh
|
|
28
|
+
Kline.
|
|
29
|
+
* Enhance generic JSON and #generate docs. Pull request #347 by Victor
|
|
30
|
+
Shepelev.
|
|
31
|
+
* Add :nodoc: for GeneratorMethods. Pull request #349 by Victor Shepelev.
|
|
32
|
+
* Baseline changes to help (JRuby) development. Pull request #371 by Karol
|
|
33
|
+
Bucek.
|
|
34
|
+
* Add metadata for rubygems.org. Pull request #379 by Alexandre ZANNI.
|
|
35
|
+
* Remove invalid JSON.generate description from JSON module rdoc. Pull
|
|
36
|
+
request #384 by Jeremy Evans.
|
|
37
|
+
* Test with TruffleRuby in CI. Pull request #402 by Benoit Daloze.
|
|
38
|
+
* Rdoc enhancements. Pull request #413 by Burdette Lamar.
|
|
39
|
+
* Fixtures/ are not being tested... Pull request #416 by Marc-André
|
|
40
|
+
Lafortune.
|
|
41
|
+
* Use frozen string for hash key. Pull request #420 by Marc-André
|
|
42
|
+
Lafortune.
|
|
43
|
+
* Added :call-seq: to RDoc for some methods. Pull request #422 by Burdette
|
|
44
|
+
Lamar.
|
|
45
|
+
* Small typo fix. Pull request #423 by Marc-André Lafortune.
|
|
46
|
+
|
|
47
|
+
## 2019-12-11 (2.3.0)
|
|
48
|
+
* Fix default of `create_additions` to always be `false` for `JSON(user_input)`
|
|
49
|
+
and `JSON.parse(user_input, nil)`.
|
|
50
|
+
Note that `JSON.load` remains with default `true` and is meant for internal
|
|
51
|
+
serialization of trusted data. [CVE-2020-10663]
|
|
52
|
+
* Fix passing args all #to_json in json/add/*.
|
|
53
|
+
* Fix encoding issues
|
|
54
|
+
* Fix issues of keyword vs positional parameter
|
|
55
|
+
* Fix JSON::Parser against bigdecimal updates
|
|
56
|
+
* Bug fixes to JRuby port
|
|
57
|
+
|
|
3
58
|
## 2019-02-21 (2.2.0)
|
|
4
59
|
* Adds support for 2.6 BigDecimal and ruby standard library Set datetype.
|
|
5
60
|
|
data/README.md
CHANGED
|
@@ -390,6 +390,22 @@ Here are the median comparisons for completeness' sake:
|
|
|
390
390
|
secs/call
|
|
391
391
|
```
|
|
392
392
|
|
|
393
|
+
## Development
|
|
394
|
+
|
|
395
|
+
### Release
|
|
396
|
+
|
|
397
|
+
Update the json.gemspec and json-java.gemspec.
|
|
398
|
+
|
|
399
|
+
```
|
|
400
|
+
rbenv shell 2.6.5
|
|
401
|
+
rake build
|
|
402
|
+
gem push pkg/json-2.3.0.gem
|
|
403
|
+
|
|
404
|
+
rbenv shell jruby-9.2.9.0
|
|
405
|
+
rake build
|
|
406
|
+
gem push pkg/json-2.3.0-java.gem
|
|
407
|
+
```
|
|
408
|
+
|
|
393
409
|
## Author
|
|
394
410
|
|
|
395
411
|
Florian Frank <mailto:flori@ping.de>
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.5.1
|
|
@@ -15,14 +15,13 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
|
|
|
15
15
|
#endif
|
|
16
16
|
mFloat, mString, mString_Extend,
|
|
17
17
|
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
|
|
18
|
-
eNestingError
|
|
19
|
-
i_SAFE_STATE_PROTOTYPE;
|
|
18
|
+
eNestingError;
|
|
20
19
|
|
|
21
20
|
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
|
|
22
21
|
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
|
|
23
22
|
i_pack, i_unpack, i_create_id, i_extend, i_key_p,
|
|
24
23
|
i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
|
|
25
|
-
i_buffer_initial_length, i_dup;
|
|
24
|
+
i_buffer_initial_length, i_dup, i_escape_slash;
|
|
26
25
|
|
|
27
26
|
/*
|
|
28
27
|
* Copyright 2001-2004 Unicode, Inc.
|
|
@@ -130,7 +129,7 @@ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
|
|
|
130
129
|
|
|
131
130
|
/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
|
|
132
131
|
* and control characters are JSON escaped. */
|
|
133
|
-
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
|
|
132
|
+
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash)
|
|
134
133
|
{
|
|
135
134
|
const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
|
|
136
135
|
const UTF8 *sourceEnd = source + RSTRING_LEN(string);
|
|
@@ -180,6 +179,11 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
|
|
|
180
179
|
case '"':
|
|
181
180
|
fbuffer_append(buffer, "\\\"", 2);
|
|
182
181
|
break;
|
|
182
|
+
case '/':
|
|
183
|
+
if(escape_slash) {
|
|
184
|
+
fbuffer_append(buffer, "\\/", 2);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
183
187
|
default:
|
|
184
188
|
fbuffer_append_char(buffer, (char)ch);
|
|
185
189
|
break;
|
|
@@ -229,7 +233,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
|
|
|
229
233
|
* characters required by the JSON standard are JSON escaped. The remaining
|
|
230
234
|
* characters (should be UTF8) are just passed through and appended to the
|
|
231
235
|
* result. */
|
|
232
|
-
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
|
236
|
+
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash)
|
|
233
237
|
{
|
|
234
238
|
const char *ptr = RSTRING_PTR(string), *p;
|
|
235
239
|
unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
|
|
@@ -280,6 +284,12 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
|
|
280
284
|
escape = "\\\"";
|
|
281
285
|
escape_len = 2;
|
|
282
286
|
break;
|
|
287
|
+
case '/':
|
|
288
|
+
if(escape_slash) {
|
|
289
|
+
escape = "\\/";
|
|
290
|
+
escape_len = 2;
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
283
293
|
default:
|
|
284
294
|
{
|
|
285
295
|
unsigned short clen = 1;
|
|
@@ -328,6 +338,76 @@ static char *fstrndup(const char *ptr, unsigned long len) {
|
|
|
328
338
|
*
|
|
329
339
|
*/
|
|
330
340
|
|
|
341
|
+
/* Explanation of the following: that's the only way to not pollute
|
|
342
|
+
* standard library's docs with GeneratorMethods::<ClassName> which
|
|
343
|
+
* are uninformative and take a large place in a list of classes
|
|
344
|
+
*/
|
|
345
|
+
|
|
346
|
+
/*
|
|
347
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods
|
|
348
|
+
* :nodoc:
|
|
349
|
+
*/
|
|
350
|
+
|
|
351
|
+
/*
|
|
352
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Array
|
|
353
|
+
* :nodoc:
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
/*
|
|
357
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
|
|
358
|
+
* :nodoc:
|
|
359
|
+
*/
|
|
360
|
+
|
|
361
|
+
/*
|
|
362
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
|
|
363
|
+
* :nodoc:
|
|
364
|
+
*/
|
|
365
|
+
|
|
366
|
+
/*
|
|
367
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
|
|
368
|
+
* :nodoc:
|
|
369
|
+
*/
|
|
370
|
+
|
|
371
|
+
/*
|
|
372
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Float
|
|
373
|
+
* :nodoc:
|
|
374
|
+
*/
|
|
375
|
+
|
|
376
|
+
/*
|
|
377
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
|
|
378
|
+
* :nodoc:
|
|
379
|
+
*/
|
|
380
|
+
|
|
381
|
+
/*
|
|
382
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
|
|
383
|
+
* :nodoc:
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
/*
|
|
387
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
|
|
388
|
+
* :nodoc:
|
|
389
|
+
*/
|
|
390
|
+
|
|
391
|
+
/*
|
|
392
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Object
|
|
393
|
+
* :nodoc:
|
|
394
|
+
*/
|
|
395
|
+
|
|
396
|
+
/*
|
|
397
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::String
|
|
398
|
+
* :nodoc:
|
|
399
|
+
*/
|
|
400
|
+
|
|
401
|
+
/*
|
|
402
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
|
|
403
|
+
* :nodoc:
|
|
404
|
+
*/
|
|
405
|
+
|
|
406
|
+
/*
|
|
407
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
|
|
408
|
+
* :nodoc:
|
|
409
|
+
*/
|
|
410
|
+
|
|
331
411
|
/*
|
|
332
412
|
* call-seq: to_json(state = nil)
|
|
333
413
|
*
|
|
@@ -539,13 +619,18 @@ static size_t State_memsize(const void *ptr)
|
|
|
539
619
|
return size;
|
|
540
620
|
}
|
|
541
621
|
|
|
622
|
+
#ifndef HAVE_RB_EXT_RACTOR_SAFE
|
|
623
|
+
# undef RUBY_TYPED_FROZEN_SHAREABLE
|
|
624
|
+
# define RUBY_TYPED_FROZEN_SHAREABLE 0
|
|
625
|
+
#endif
|
|
626
|
+
|
|
542
627
|
#ifdef NEW_TYPEDDATA_WRAPPER
|
|
543
628
|
static const rb_data_type_t JSON_Generator_State_type = {
|
|
544
629
|
"JSON/Generator/State",
|
|
545
630
|
{NULL, State_free, State_memsize,},
|
|
546
631
|
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
547
632
|
0, 0,
|
|
548
|
-
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
633
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
549
634
|
#endif
|
|
550
635
|
};
|
|
551
636
|
#endif
|
|
@@ -646,6 +731,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
|
|
|
646
731
|
state->allow_nan = RTEST(tmp);
|
|
647
732
|
tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
|
|
648
733
|
state->ascii_only = RTEST(tmp);
|
|
734
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
|
|
735
|
+
state->escape_slash = RTEST(tmp);
|
|
649
736
|
return self;
|
|
650
737
|
}
|
|
651
738
|
|
|
@@ -680,6 +767,7 @@ static VALUE cState_to_h(VALUE self)
|
|
|
680
767
|
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
|
|
681
768
|
rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
|
|
682
769
|
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
|
|
770
|
+
rb_hash_aset(result, ID2SYM(i_escape_slash), state->escape_slash ? Qtrue : Qfalse);
|
|
683
771
|
rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
|
|
684
772
|
rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
|
|
685
773
|
return result;
|
|
@@ -864,9 +952,9 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
|
|
|
864
952
|
}
|
|
865
953
|
#endif
|
|
866
954
|
if (state->ascii_only) {
|
|
867
|
-
convert_UTF8_to_JSON_ASCII(buffer, obj);
|
|
955
|
+
convert_UTF8_to_JSON_ASCII(buffer, obj, state->escape_slash);
|
|
868
956
|
} else {
|
|
869
|
-
convert_UTF8_to_JSON(buffer, obj);
|
|
957
|
+
convert_UTF8_to_JSON(buffer, obj, state->escape_slash);
|
|
870
958
|
}
|
|
871
959
|
fbuffer_append_char(buffer, '"');
|
|
872
960
|
}
|
|
@@ -1026,7 +1114,7 @@ static VALUE cState_generate(VALUE self, VALUE obj)
|
|
|
1026
1114
|
* generated, otherwise an exception is thrown, if these values are
|
|
1027
1115
|
* encountered. This options defaults to false.
|
|
1028
1116
|
* * *ascii_only*: true if only ASCII characters should be generated. This
|
|
1029
|
-
*
|
|
1117
|
+
* option defaults to false.
|
|
1030
1118
|
* * *buffer_initial_length*: sets the initial length of the generator's
|
|
1031
1119
|
* internal buffer.
|
|
1032
1120
|
*/
|
|
@@ -1082,8 +1170,7 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
|
|
|
1082
1170
|
} else if (rb_obj_is_kind_of(opts, rb_cHash)) {
|
|
1083
1171
|
return rb_funcall(self, i_new, 1, opts);
|
|
1084
1172
|
} else {
|
|
1085
|
-
|
|
1086
|
-
return rb_funcall(prototype, i_dup, 0);
|
|
1173
|
+
return rb_class_new_instance(0, NULL, cState);
|
|
1087
1174
|
}
|
|
1088
1175
|
}
|
|
1089
1176
|
|
|
@@ -1307,6 +1394,31 @@ static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
|
|
|
1307
1394
|
return state->max_nesting = FIX2LONG(depth);
|
|
1308
1395
|
}
|
|
1309
1396
|
|
|
1397
|
+
/*
|
|
1398
|
+
* call-seq: escape_slash
|
|
1399
|
+
*
|
|
1400
|
+
* If this boolean is true, the forward slashes will be escaped in
|
|
1401
|
+
* the json output.
|
|
1402
|
+
*/
|
|
1403
|
+
static VALUE cState_escape_slash(VALUE self)
|
|
1404
|
+
{
|
|
1405
|
+
GET_STATE(self);
|
|
1406
|
+
return state->escape_slash ? Qtrue : Qfalse;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
/*
|
|
1410
|
+
* call-seq: escape_slash=(depth)
|
|
1411
|
+
*
|
|
1412
|
+
* This sets whether or not the forward slashes will be escaped in
|
|
1413
|
+
* the json output.
|
|
1414
|
+
*/
|
|
1415
|
+
static VALUE cState_escape_slash_set(VALUE self, VALUE enable)
|
|
1416
|
+
{
|
|
1417
|
+
GET_STATE(self);
|
|
1418
|
+
state->escape_slash = RTEST(enable);
|
|
1419
|
+
return Qnil;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1310
1422
|
/*
|
|
1311
1423
|
* call-seq: allow_nan?
|
|
1312
1424
|
*
|
|
@@ -1390,6 +1502,10 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
|
|
|
1390
1502
|
*/
|
|
1391
1503
|
void Init_generator(void)
|
|
1392
1504
|
{
|
|
1505
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
|
1506
|
+
rb_ext_ractor_safe(true);
|
|
1507
|
+
#endif
|
|
1508
|
+
|
|
1393
1509
|
#undef rb_intern
|
|
1394
1510
|
rb_require("json/common");
|
|
1395
1511
|
|
|
@@ -1419,6 +1535,9 @@ void Init_generator(void)
|
|
|
1419
1535
|
rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
|
|
1420
1536
|
rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
|
|
1421
1537
|
rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
|
|
1538
|
+
rb_define_method(cState, "escape_slash", cState_escape_slash, 0);
|
|
1539
|
+
rb_define_method(cState, "escape_slash?", cState_escape_slash, 0);
|
|
1540
|
+
rb_define_method(cState, "escape_slash=", cState_escape_slash_set, 1);
|
|
1422
1541
|
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
|
|
1423
1542
|
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
|
|
1424
1543
|
rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
|
|
@@ -1475,6 +1594,7 @@ void Init_generator(void)
|
|
|
1475
1594
|
i_object_nl = rb_intern("object_nl");
|
|
1476
1595
|
i_array_nl = rb_intern("array_nl");
|
|
1477
1596
|
i_max_nesting = rb_intern("max_nesting");
|
|
1597
|
+
i_escape_slash = rb_intern("escape_slash");
|
|
1478
1598
|
i_allow_nan = rb_intern("allow_nan");
|
|
1479
1599
|
i_ascii_only = rb_intern("ascii_only");
|
|
1480
1600
|
i_depth = rb_intern("depth");
|
|
@@ -1495,5 +1615,4 @@ void Init_generator(void)
|
|
|
1495
1615
|
i_encoding = rb_intern("encoding");
|
|
1496
1616
|
i_encode = rb_intern("encode");
|
|
1497
1617
|
#endif
|
|
1498
|
-
i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
|
|
1499
1618
|
}
|
|
@@ -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"
|
|
@@ -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
|
|
990
|
+
#line 346 "parser.rl"
|
|
987
991
|
|
|
988
992
|
|
|
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
|
-
|
|
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;
|
|
@@ -1677,7 +1693,22 @@ case 7:
|
|
|
1677
1693
|
if (json->symbolize_names && json->parsing_name) {
|
|
1678
1694
|
*result = rb_str_intern(*result);
|
|
1679
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
|
|
1680
1710
|
rb_str_resize(*result, RSTRING_LEN(*result));
|
|
1711
|
+
# endif
|
|
1681
1712
|
}
|
|
1682
1713
|
if (cs >= JSON_string_first_final) {
|
|
1683
1714
|
return p + 1;
|
|
@@ -1785,6 +1816,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
1785
1816
|
} else {
|
|
1786
1817
|
json->symbolize_names = 0;
|
|
1787
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
|
+
}
|
|
1788
1825
|
tmp = ID2SYM(i_create_additions);
|
|
1789
1826
|
if (option_given_p(opts, tmp)) {
|
|
1790
1827
|
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
|
@@ -1848,7 +1885,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
1848
1885
|
}
|
|
1849
1886
|
|
|
1850
1887
|
|
|
1851
|
-
#line
|
|
1888
|
+
#line 1878 "parser.c"
|
|
1852
1889
|
enum {JSON_start = 1};
|
|
1853
1890
|
enum {JSON_first_final = 10};
|
|
1854
1891
|
enum {JSON_error = 0};
|
|
@@ -1856,7 +1893,7 @@ enum {JSON_error = 0};
|
|
|
1856
1893
|
enum {JSON_en_main = 1};
|
|
1857
1894
|
|
|
1858
1895
|
|
|
1859
|
-
#line
|
|
1896
|
+
#line 786 "parser.rl"
|
|
1860
1897
|
|
|
1861
1898
|
|
|
1862
1899
|
/*
|
|
@@ -1873,16 +1910,16 @@ static VALUE cParser_parse(VALUE self)
|
|
|
1873
1910
|
GET_PARSER;
|
|
1874
1911
|
|
|
1875
1912
|
|
|
1876
|
-
#line
|
|
1913
|
+
#line 1903 "parser.c"
|
|
1877
1914
|
{
|
|
1878
1915
|
cs = JSON_start;
|
|
1879
1916
|
}
|
|
1880
1917
|
|
|
1881
|
-
#line
|
|
1918
|
+
#line 802 "parser.rl"
|
|
1882
1919
|
p = json->source;
|
|
1883
1920
|
pe = p + json->len;
|
|
1884
1921
|
|
|
1885
|
-
#line
|
|
1922
|
+
#line 1912 "parser.c"
|
|
1886
1923
|
{
|
|
1887
1924
|
if ( p == pe )
|
|
1888
1925
|
goto _test_eof;
|
|
@@ -1916,7 +1953,7 @@ st0:
|
|
|
1916
1953
|
cs = 0;
|
|
1917
1954
|
goto _out;
|
|
1918
1955
|
tr2:
|
|
1919
|
-
#line
|
|
1956
|
+
#line 778 "parser.rl"
|
|
1920
1957
|
{
|
|
1921
1958
|
char *np = JSON_parse_value(json, p, pe, &result, 0);
|
|
1922
1959
|
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
|
|
@@ -1926,7 +1963,7 @@ st10:
|
|
|
1926
1963
|
if ( ++p == pe )
|
|
1927
1964
|
goto _test_eof10;
|
|
1928
1965
|
case 10:
|
|
1929
|
-
#line
|
|
1966
|
+
#line 1956 "parser.c"
|
|
1930
1967
|
switch( (*p) ) {
|
|
1931
1968
|
case 13: goto st10;
|
|
1932
1969
|
case 32: goto st10;
|
|
@@ -2015,7 +2052,7 @@ case 9:
|
|
|
2015
2052
|
_out: {}
|
|
2016
2053
|
}
|
|
2017
2054
|
|
|
2018
|
-
#line
|
|
2055
|
+
#line 805 "parser.rl"
|
|
2019
2056
|
|
|
2020
2057
|
if (cs >= JSON_first_final && p == pe) {
|
|
2021
2058
|
return result;
|
|
@@ -2082,6 +2119,10 @@ static VALUE cParser_source(VALUE self)
|
|
|
2082
2119
|
|
|
2083
2120
|
void Init_parser(void)
|
|
2084
2121
|
{
|
|
2122
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
|
2123
|
+
rb_ext_ractor_safe(true);
|
|
2124
|
+
#endif
|
|
2125
|
+
|
|
2085
2126
|
#undef rb_intern
|
|
2086
2127
|
rb_require("json/common");
|
|
2087
2128
|
mJSON = rb_define_module("JSON");
|
|
@@ -2124,7 +2165,9 @@ void Init_parser(void)
|
|
|
2124
2165
|
i_aref = rb_intern("[]");
|
|
2125
2166
|
i_leftshift = rb_intern("<<");
|
|
2126
2167
|
i_new = rb_intern("new");
|
|
2127
|
-
|
|
2168
|
+
i_try_convert = rb_intern("try_convert");
|
|
2169
|
+
i_freeze = rb_intern("freeze");
|
|
2170
|
+
i_uminus = rb_intern("-@");
|
|
2128
2171
|
}
|
|
2129
2172
|
|
|
2130
2173
|
/*
|