json 2.6.3 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +46 -0
- data/README.md +4 -4
- data/ext/json/ext/generator/generator.c +84 -19
- data/ext/json/ext/generator/generator.h +8 -5
- data/ext/json/ext/parser/parser.c +1828 -2964
- data/ext/json/ext/parser/parser.rl +79 -94
- data/json.gemspec +7 -6
- data/lib/json/add/bigdecimal.rb +37 -8
- data/lib/json/add/complex.rb +28 -5
- data/lib/json/add/date.rb +26 -6
- data/lib/json/add/date_time.rb +25 -8
- data/lib/json/add/exception.rb +24 -6
- data/lib/json/add/ostruct.rb +26 -6
- data/lib/json/add/range.rb +32 -7
- data/lib/json/add/rational.rb +27 -5
- data/lib/json/add/regexp.rb +25 -7
- data/lib/json/add/set.rb +25 -6
- data/lib/json/add/struct.rb +28 -6
- data/lib/json/add/symbol.rb +27 -4
- data/lib/json/add/time.rb +26 -5
- data/lib/json/common.rb +27 -33
- data/lib/json/pure/generator.rb +62 -28
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +9 -0
- metadata +6 -7
- data/VERSION +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d39ddfc605399a55f202bd106776ede02812c232d813469165dfd9c06dbea5d
|
4
|
+
data.tar.gz: d168c4f8aa5fe5f13e570e454c997fb91f6946ce8b339b0ef3477486edd8e99d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3511a0cfd5365e476b39181201b0cd4ea8d415774ca524958955647bbeb9db0ddf5bbafae8f816fbb5b0459d643aa6345c63d5f3ec9443cd67c15cea50c0db57
|
7
|
+
data.tar.gz: f015ec65ce58d4d946626162d29af7e24d26689fde3162b07b7a7b45d2f90049d676d8d1c22127ae1b7a6fdfb1926a80cb865330b9da458b700682d7d626b1b0
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,38 @@
|
|
1
1
|
# Changes
|
2
2
|
|
3
|
+
### 2023-12-05 (2.7.1)
|
4
|
+
|
5
|
+
* JSON.dump: handle unenclosed hashes regression #554
|
6
|
+
* Overload kwargs in JSON.dump #556
|
7
|
+
* [DOC] RDoc for additions #557
|
8
|
+
* Fix JSON.dump overload combination #558
|
9
|
+
|
10
|
+
### 2023-12-01 (2.7.0)
|
11
|
+
|
12
|
+
* Add a strict option to Generator #519
|
13
|
+
* `escape_slash` option was renamed as `script_safe` and now also escape U+2028 and U+2029. `escape_slash` is now an alias of `script_safe` #525
|
14
|
+
* Remove unnecessary initialization of create_id in JSON.parse() #454
|
15
|
+
* Improvements to Hash#to_json in pure implementation generator #203
|
16
|
+
* Use ruby_xfree to free buffers #518
|
17
|
+
* Fix "unexpected token" offset for Infinity #507
|
18
|
+
* Avoid using deprecated BigDecimal.new on JRuby #546
|
19
|
+
* Removed code for Ruby 1.8 #540
|
20
|
+
* Rename JSON::ParseError to JSON:ParserError #530
|
21
|
+
* Call super in included hook #486
|
22
|
+
* JRuby requires a minimum of Java 8 #516
|
23
|
+
* Always indent even if empty #517
|
24
|
+
|
25
|
+
### 2022-11-30 (2.6.3)
|
26
|
+
|
27
|
+
* bugfix json/pure mixing escaped with literal unicode raises Encoding::CompatibilityError #483
|
28
|
+
* Stop including the parser source __LINE__ in exceptions #470
|
29
|
+
|
30
|
+
### 2022-11-17 (2.6.2)
|
31
|
+
|
32
|
+
* Remove unknown keyword arg from DateTime.parse #488
|
33
|
+
* Ignore java artifacts by @hsbt #489
|
34
|
+
* Fix parser bug for empty string allocation #496
|
35
|
+
|
3
36
|
### 2021-10-24 (2.6.1)
|
4
37
|
|
5
38
|
* Restore version.rb with 2.6.1
|
@@ -105,6 +138,19 @@
|
|
105
138
|
I changed these mentions to be consistent with the Ruby license setting in
|
106
139
|
the gemspec files which were already correct now.
|
107
140
|
|
141
|
+
## 2017-01-13 (1.8.6)
|
142
|
+
* Be compatible with ancient ruby 1.8 (maybe?)
|
143
|
+
|
144
|
+
## 2015-09-11 (1.8.5)
|
145
|
+
* Be compatible with ruby 2.4.0
|
146
|
+
* There were still some mentions of dual GPL licensing in the source, but JSON
|
147
|
+
has just the Ruby license that itself includes an explicit dual-licensing
|
148
|
+
clause that allows covered software to be distributed under the terms of
|
149
|
+
the Simplified BSD License instead for all ruby versions >= 1.9.3. This is
|
150
|
+
however a GPL compatible license according to the Free Software Foundation.
|
151
|
+
I changed these mentions to be consistent with the Ruby license setting in
|
152
|
+
the gemspec files which were already correct now.
|
153
|
+
|
108
154
|
## 2015-06-01 (1.8.3)
|
109
155
|
* Fix potential memory leak, thx to nobu.
|
110
156
|
|
data/README.md
CHANGED
@@ -12,8 +12,7 @@ will be two variants available:
|
|
12
12
|
extensions, which are both part of the ruby standard library.
|
13
13
|
* The quite a bit faster native extension variant, which is in parts
|
14
14
|
implemented in C or Java and comes with its own unicode conversion
|
15
|
-
functions and a parser generated by the
|
16
|
-
http://www.complang.org/ragel/ .
|
15
|
+
functions and a parser generated by the [Ragel] state machine compiler.
|
17
16
|
|
18
17
|
Both variants of the JSON generator generate UTF-8 character sequences by
|
19
18
|
default. If an :ascii\_only option with a true value is given, they escape all
|
@@ -71,8 +70,7 @@ with:
|
|
71
70
|
## Compiling the extensions yourself
|
72
71
|
|
73
72
|
If you want to create the `parser.c` file from its `parser.rl` file or draw nice
|
74
|
-
graphviz images of the state machines, you need
|
75
|
-
http://www.complang.org/ragel/
|
73
|
+
graphviz images of the state machines, you need [Ragel].
|
76
74
|
|
77
75
|
## Usage
|
78
76
|
|
@@ -423,3 +421,5 @@ The latest version of this library can be downloaded at
|
|
423
421
|
Online Documentation should be located at
|
424
422
|
|
425
423
|
* https://www.rubydoc.info/gems/json
|
424
|
+
|
425
|
+
[Ragel]: http://www.colm.net/open-source/ragel/
|
@@ -16,7 +16,7 @@ static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
|
|
16
16
|
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
|
17
17
|
i_pack, i_unpack, i_create_id, i_extend, i_key_p,
|
18
18
|
i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
|
19
|
-
i_buffer_initial_length, i_dup, i_escape_slash;
|
19
|
+
i_buffer_initial_length, i_dup, i_script_safe, i_escape_slash, i_strict;
|
20
20
|
|
21
21
|
/*
|
22
22
|
* Copyright 2001-2004 Unicode, Inc.
|
@@ -124,7 +124,7 @@ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
|
|
124
124
|
|
125
125
|
/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
|
126
126
|
* and control characters are JSON escaped. */
|
127
|
-
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char
|
127
|
+
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char script_safe)
|
128
128
|
{
|
129
129
|
const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
|
130
130
|
const UTF8 *sourceEnd = source + RSTRING_LEN(string);
|
@@ -175,7 +175,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escap
|
|
175
175
|
fbuffer_append(buffer, "\\\"", 2);
|
176
176
|
break;
|
177
177
|
case '/':
|
178
|
-
if(
|
178
|
+
if(script_safe) {
|
179
179
|
fbuffer_append(buffer, "\\/", 2);
|
180
180
|
break;
|
181
181
|
}
|
@@ -228,7 +228,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escap
|
|
228
228
|
* characters required by the JSON standard are JSON escaped. The remaining
|
229
229
|
* characters (should be UTF8) are just passed through and appended to the
|
230
230
|
* result. */
|
231
|
-
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char
|
231
|
+
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char script_safe)
|
232
232
|
{
|
233
233
|
const char *ptr = RSTRING_PTR(string), *p;
|
234
234
|
unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
|
@@ -280,7 +280,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slas
|
|
280
280
|
escape_len = 2;
|
281
281
|
break;
|
282
282
|
case '/':
|
283
|
-
if(
|
283
|
+
if(script_safe) {
|
284
284
|
escape = "\\/";
|
285
285
|
escape_len = 2;
|
286
286
|
break;
|
@@ -294,6 +294,22 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slas
|
|
294
294
|
rb_raise(rb_path2class("JSON::GeneratorError"),
|
295
295
|
"partial character in source, but hit end");
|
296
296
|
}
|
297
|
+
|
298
|
+
if (script_safe && c == 0xE2) {
|
299
|
+
unsigned char c2 = (unsigned char) *(p+1);
|
300
|
+
unsigned char c3 = (unsigned char) *(p+2);
|
301
|
+
if (c2 == 0x80 && (c3 == 0xA8 || c3 == 0xA9)) {
|
302
|
+
fbuffer_append(buffer, ptr + start, end - start);
|
303
|
+
start = end = (end + clen);
|
304
|
+
if (c3 == 0xA8) {
|
305
|
+
fbuffer_append(buffer, "\\u2028", 6);
|
306
|
+
} else {
|
307
|
+
fbuffer_append(buffer, "\\u2029", 6);
|
308
|
+
}
|
309
|
+
continue;
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
297
313
|
if (!isLegalUTF8((UTF8 *) p, clen)) {
|
298
314
|
rb_raise(rb_path2class("JSON::GeneratorError"),
|
299
315
|
"source sequence is illegal/malformed utf-8");
|
@@ -478,6 +494,7 @@ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
|
|
478
494
|
*/
|
479
495
|
static VALUE mString_included_s(VALUE self, VALUE modul) {
|
480
496
|
VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
|
497
|
+
rb_call_super(1, &modul);
|
481
498
|
return result;
|
482
499
|
}
|
483
500
|
|
@@ -726,8 +743,14 @@ static VALUE cState_configure(VALUE self, VALUE opts)
|
|
726
743
|
state->allow_nan = RTEST(tmp);
|
727
744
|
tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
|
728
745
|
state->ascii_only = RTEST(tmp);
|
729
|
-
tmp = rb_hash_aref(opts, ID2SYM(
|
730
|
-
state->
|
746
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_script_safe));
|
747
|
+
state->script_safe = RTEST(tmp);
|
748
|
+
if (!state->script_safe) {
|
749
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
|
750
|
+
state->script_safe = RTEST(tmp);
|
751
|
+
}
|
752
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_strict));
|
753
|
+
state->strict = RTEST(tmp);
|
731
754
|
return self;
|
732
755
|
}
|
733
756
|
|
@@ -762,7 +785,8 @@ static VALUE cState_to_h(VALUE self)
|
|
762
785
|
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
|
763
786
|
rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
|
764
787
|
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
|
765
|
-
rb_hash_aset(result, ID2SYM(
|
788
|
+
rb_hash_aset(result, ID2SYM(i_script_safe), state->script_safe ? Qtrue : Qfalse);
|
789
|
+
rb_hash_aset(result, ID2SYM(i_strict), state->strict ? Qtrue : Qfalse);
|
766
790
|
rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
|
767
791
|
rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
|
768
792
|
return result;
|
@@ -947,9 +971,9 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
|
|
947
971
|
}
|
948
972
|
#endif
|
949
973
|
if (state->ascii_only) {
|
950
|
-
convert_UTF8_to_JSON_ASCII(buffer, obj, state->
|
974
|
+
convert_UTF8_to_JSON_ASCII(buffer, obj, state->script_safe);
|
951
975
|
} else {
|
952
|
-
convert_UTF8_to_JSON(buffer, obj, state->
|
976
|
+
convert_UTF8_to_JSON(buffer, obj, state->script_safe);
|
953
977
|
}
|
954
978
|
fbuffer_append_char(buffer, '"');
|
955
979
|
}
|
@@ -1028,6 +1052,8 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s
|
|
1028
1052
|
generate_json_bignum(buffer, Vstate, state, obj);
|
1029
1053
|
} else if (klass == rb_cFloat) {
|
1030
1054
|
generate_json_float(buffer, Vstate, state, obj);
|
1055
|
+
} else if (state->strict) {
|
1056
|
+
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(CLASS_OF(obj)));
|
1031
1057
|
} else if (rb_respond_to(obj, i_to_json)) {
|
1032
1058
|
tmp = rb_funcall(obj, i_to_json, 1, Vstate);
|
1033
1059
|
Check_Type(tmp, T_STRING);
|
@@ -1390,27 +1416,58 @@ static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
|
|
1390
1416
|
}
|
1391
1417
|
|
1392
1418
|
/*
|
1393
|
-
* call-seq:
|
1419
|
+
* call-seq: script_safe
|
1394
1420
|
*
|
1395
1421
|
* If this boolean is true, the forward slashes will be escaped in
|
1396
1422
|
* the json output.
|
1397
1423
|
*/
|
1398
|
-
static VALUE
|
1424
|
+
static VALUE cState_script_safe(VALUE self)
|
1399
1425
|
{
|
1400
1426
|
GET_STATE(self);
|
1401
|
-
return state->
|
1427
|
+
return state->script_safe ? Qtrue : Qfalse;
|
1402
1428
|
}
|
1403
1429
|
|
1404
1430
|
/*
|
1405
|
-
* call-seq:
|
1431
|
+
* call-seq: script_safe=(enable)
|
1406
1432
|
*
|
1407
1433
|
* This sets whether or not the forward slashes will be escaped in
|
1408
1434
|
* the json output.
|
1409
1435
|
*/
|
1410
|
-
static VALUE
|
1436
|
+
static VALUE cState_script_safe_set(VALUE self, VALUE enable)
|
1437
|
+
{
|
1438
|
+
GET_STATE(self);
|
1439
|
+
state->script_safe = RTEST(enable);
|
1440
|
+
return Qnil;
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
/*
|
1444
|
+
* call-seq: strict
|
1445
|
+
*
|
1446
|
+
* If this boolean is false, types unsupported by the JSON format will
|
1447
|
+
* be serialized as strings.
|
1448
|
+
* If this boolean is true, types unsupported by the JSON format will
|
1449
|
+
* raise a JSON::GeneratorError.
|
1450
|
+
*/
|
1451
|
+
static VALUE cState_strict(VALUE self)
|
1452
|
+
{
|
1453
|
+
GET_STATE(self);
|
1454
|
+
return state->strict ? Qtrue : Qfalse;
|
1455
|
+
}
|
1456
|
+
|
1457
|
+
/*
|
1458
|
+
* call-seq: strict=(enable)
|
1459
|
+
*
|
1460
|
+
* This sets whether or not to serialize types unsupported by the
|
1461
|
+
* JSON format as strings.
|
1462
|
+
* If this boolean is false, types unsupported by the JSON format will
|
1463
|
+
* be serialized as strings.
|
1464
|
+
* If this boolean is true, types unsupported by the JSON format will
|
1465
|
+
* raise a JSON::GeneratorError.
|
1466
|
+
*/
|
1467
|
+
static VALUE cState_strict_set(VALUE self, VALUE enable)
|
1411
1468
|
{
|
1412
1469
|
GET_STATE(self);
|
1413
|
-
state->
|
1470
|
+
state->strict = RTEST(enable);
|
1414
1471
|
return Qnil;
|
1415
1472
|
}
|
1416
1473
|
|
@@ -1530,9 +1587,15 @@ void Init_generator(void)
|
|
1530
1587
|
rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
|
1531
1588
|
rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
|
1532
1589
|
rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
|
1533
|
-
rb_define_method(cState, "
|
1534
|
-
rb_define_method(cState, "
|
1535
|
-
rb_define_method(cState, "
|
1590
|
+
rb_define_method(cState, "script_safe", cState_script_safe, 0);
|
1591
|
+
rb_define_method(cState, "script_safe?", cState_script_safe, 0);
|
1592
|
+
rb_define_method(cState, "script_safe=", cState_script_safe_set, 1);
|
1593
|
+
rb_define_alias(cState, "escape_slash", "script_safe");
|
1594
|
+
rb_define_alias(cState, "escape_slash?", "script_safe?");
|
1595
|
+
rb_define_alias(cState, "escape_slash=", "script_safe=");
|
1596
|
+
rb_define_method(cState, "strict", cState_strict, 0);
|
1597
|
+
rb_define_method(cState, "strict?", cState_strict, 0);
|
1598
|
+
rb_define_method(cState, "strict=", cState_strict_set, 1);
|
1536
1599
|
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
|
1537
1600
|
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
|
1538
1601
|
rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
|
@@ -1589,7 +1652,9 @@ void Init_generator(void)
|
|
1589
1652
|
i_object_nl = rb_intern("object_nl");
|
1590
1653
|
i_array_nl = rb_intern("array_nl");
|
1591
1654
|
i_max_nesting = rb_intern("max_nesting");
|
1655
|
+
i_script_safe = rb_intern("script_safe");
|
1592
1656
|
i_escape_slash = rb_intern("escape_slash");
|
1657
|
+
i_strict = rb_intern("strict");
|
1593
1658
|
i_allow_nan = rb_intern("allow_nan");
|
1594
1659
|
i_ascii_only = rb_intern("ascii_only");
|
1595
1660
|
i_depth = rb_intern("depth");
|
@@ -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, char
|
53
|
-
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char
|
52
|
+
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char script_safe);
|
53
|
+
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char script_safe);
|
54
54
|
static char *fstrndup(const char *ptr, unsigned long len);
|
55
55
|
|
56
56
|
/* ruby api and some helpers */
|
@@ -72,7 +72,8 @@ typedef struct JSON_Generator_StateStruct {
|
|
72
72
|
long max_nesting;
|
73
73
|
char allow_nan;
|
74
74
|
char ascii_only;
|
75
|
-
char
|
75
|
+
char script_safe;
|
76
|
+
char strict;
|
76
77
|
long depth;
|
77
78
|
long buffer_initial_length;
|
78
79
|
} JSON_Generator_State;
|
@@ -151,8 +152,10 @@ static VALUE cState_allow_nan_p(VALUE self);
|
|
151
152
|
static VALUE cState_ascii_only_p(VALUE self);
|
152
153
|
static VALUE cState_depth(VALUE self);
|
153
154
|
static VALUE cState_depth_set(VALUE self, VALUE depth);
|
154
|
-
static VALUE
|
155
|
-
static VALUE
|
155
|
+
static VALUE cState_script_safe(VALUE self);
|
156
|
+
static VALUE cState_script_safe_set(VALUE self, VALUE depth);
|
157
|
+
static VALUE cState_strict(VALUE self);
|
158
|
+
static VALUE cState_strict_set(VALUE self, VALUE strict);
|
156
159
|
static FBuffer *cState_prepare_buffer(VALUE self);
|
157
160
|
#ifndef ZALLOC
|
158
161
|
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
|