json 1.8.1 → 1.8.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.travis.yml +10 -12
- data/CHANGES +23 -0
- data/Gemfile +1 -5
- data/{README.rdoc → README.md} +34 -47
- data/Rakefile +10 -20
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +10 -1
- data/ext/json/ext/generator/extconf.rb +0 -10
- data/ext/json/ext/generator/generator.c +85 -28
- data/ext/json/ext/generator/generator.h +34 -5
- data/ext/json/ext/parser/extconf.rb +0 -10
- data/ext/json/ext/parser/parser.c +166 -130
- data/ext/json/ext/parser/parser.h +19 -4
- data/ext/json/ext/parser/parser.rl +84 -48
- data/ext/json/extconf.rb +3 -0
- data/java/src/json/ext/ByteListTranscoder.java +1 -2
- data/java/src/json/ext/Generator.java +9 -7
- data/java/src/json/ext/GeneratorMethods.java +1 -2
- data/java/src/json/ext/GeneratorService.java +1 -2
- data/java/src/json/ext/GeneratorState.java +1 -2
- data/java/src/json/ext/OptionsReader.java +1 -2
- data/java/src/json/ext/Parser.java +87 -87
- data/java/src/json/ext/Parser.rl +7 -7
- data/java/src/json/ext/ParserService.java +1 -2
- data/java/src/json/ext/RuntimeInfo.java +1 -2
- data/java/src/json/ext/StringDecoder.java +1 -2
- data/java/src/json/ext/StringEncoder.java +5 -0
- data/java/src/json/ext/Utils.java +1 -2
- data/json-java.gemspec +16 -1
- data/json.gemspec +0 -0
- data/json_pure.gemspec +23 -26
- data/lib/json/add/complex.rb +7 -1
- data/lib/json/add/rational.rb +5 -0
- data/lib/json/add/time.rb +1 -1
- data/lib/json/common.rb +5 -5
- data/lib/json/pure/generator.rb +10 -2
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +8 -34
- data/tests/test_json_generate.rb +34 -8
- data/tools/diff.sh +18 -0
- metadata +39 -39
- data/COPYING +0 -58
- data/COPYING-json-jruby +0 -57
- data/GPL +0 -340
@@ -51,7 +51,7 @@ typedef struct JSON_ParserStruct {
|
|
51
51
|
if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
|
52
52
|
#define GET_PARSER_INIT \
|
53
53
|
JSON_Parser *json; \
|
54
|
-
|
54
|
+
TypedData_Get_Struct(self, JSON_Parser, &JSON_Parser_type, json)
|
55
55
|
|
56
56
|
#define MinusInfinity "-Infinity"
|
57
57
|
#define EVIL 0x666
|
@@ -68,10 +68,25 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
68
68
|
static VALUE convert_encoding(VALUE source);
|
69
69
|
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
|
70
70
|
static VALUE cParser_parse(VALUE self);
|
71
|
-
static
|
72
|
-
static void
|
73
|
-
static void JSON_free(JSON_Parser *json);
|
71
|
+
static void JSON_mark(void *json);
|
72
|
+
static void JSON_free(void *json);
|
74
73
|
static VALUE cJSON_parser_s_allocate(VALUE klass);
|
75
74
|
static VALUE cParser_source(VALUE self);
|
75
|
+
#ifndef ZALLOC
|
76
|
+
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
|
77
|
+
static inline void *ruby_zalloc(size_t n)
|
78
|
+
{
|
79
|
+
void *p = ruby_xmalloc(n);
|
80
|
+
memset(p, 0, n);
|
81
|
+
return p;
|
82
|
+
}
|
83
|
+
#endif
|
84
|
+
#ifdef TypedData_Make_Struct
|
85
|
+
static const rb_data_type_t JSON_Parser_type;
|
86
|
+
#define NEW_TYPEDDATA_WRAPPER 1
|
87
|
+
#else
|
88
|
+
#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json)
|
89
|
+
#define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json)
|
90
|
+
#endif
|
76
91
|
|
77
92
|
#endif
|
@@ -1,6 +1,28 @@
|
|
1
1
|
#include "../fbuffer/fbuffer.h"
|
2
2
|
#include "parser.h"
|
3
3
|
|
4
|
+
#if defined HAVE_RUBY_ENCODING_H
|
5
|
+
# define EXC_ENCODING UTF_8,
|
6
|
+
# ifndef HAVE_RB_ENC_RAISE
|
7
|
+
static void
|
8
|
+
enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
|
9
|
+
{
|
10
|
+
va_list args;
|
11
|
+
VALUE mesg;
|
12
|
+
|
13
|
+
va_start(args, fmt);
|
14
|
+
mesg = rb_enc_vsprintf(enc, fmt, args);
|
15
|
+
va_end(args);
|
16
|
+
|
17
|
+
rb_exc_raise(rb_exc_new3(exc, mesg));
|
18
|
+
}
|
19
|
+
# define rb_enc_raise enc_raise
|
20
|
+
# endif
|
21
|
+
#else
|
22
|
+
# define EXC_ENCODING /* nothing */
|
23
|
+
# define rb_enc_raise rb_raise
|
24
|
+
#endif
|
25
|
+
|
4
26
|
/* unicode */
|
5
27
|
|
6
28
|
static const char digit_values[256] = {
|
@@ -26,16 +48,16 @@ static UTF32 unescape_unicode(const unsigned char *p)
|
|
26
48
|
UTF32 result = 0;
|
27
49
|
b = digit_values[p[0]];
|
28
50
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
29
|
-
result = (result << 4) | b;
|
51
|
+
result = (result << 4) | (unsigned char)b;
|
30
52
|
b = digit_values[p[1]];
|
31
|
-
result = (result << 4) | b;
|
32
53
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
54
|
+
result = (result << 4) | (unsigned char)b;
|
33
55
|
b = digit_values[p[2]];
|
34
|
-
result = (result << 4) | b;
|
35
56
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
57
|
+
result = (result << 4) | (unsigned char)b;
|
36
58
|
b = digit_values[p[3]];
|
37
|
-
result = (result << 4) | b;
|
38
59
|
if (b < 0) return UNI_REPLACEMENT_CHAR;
|
60
|
+
result = (result << 4) | (unsigned char)b;
|
39
61
|
return result;
|
40
62
|
}
|
41
63
|
|
@@ -66,9 +88,7 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
|
|
66
88
|
}
|
67
89
|
|
68
90
|
#ifdef HAVE_RUBY_ENCODING_H
|
69
|
-
static
|
70
|
-
CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
|
71
|
-
static ID i_encoding, i_encode;
|
91
|
+
static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
|
72
92
|
#else
|
73
93
|
static ID i_iconv;
|
74
94
|
#endif
|
@@ -206,14 +226,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
206
226
|
if (json->allow_nan) {
|
207
227
|
*result = CNaN;
|
208
228
|
} else {
|
209
|
-
|
229
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
|
210
230
|
}
|
211
231
|
}
|
212
232
|
action parse_infinity {
|
213
233
|
if (json->allow_nan) {
|
214
234
|
*result = CInfinity;
|
215
235
|
} else {
|
216
|
-
|
236
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
|
217
237
|
}
|
218
238
|
}
|
219
239
|
action parse_string {
|
@@ -229,7 +249,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
229
249
|
fexec p + 10;
|
230
250
|
fhold; fbreak;
|
231
251
|
} else {
|
232
|
-
|
252
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
233
253
|
}
|
234
254
|
}
|
235
255
|
np = JSON_parse_float(json, fpc, pe, result);
|
@@ -396,7 +416,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
396
416
|
if(cs >= JSON_array_first_final) {
|
397
417
|
return p + 1;
|
398
418
|
} else {
|
399
|
-
|
419
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
400
420
|
return NULL;
|
401
421
|
}
|
402
422
|
}
|
@@ -550,29 +570,29 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
550
570
|
|
551
571
|
static VALUE convert_encoding(VALUE source)
|
552
572
|
{
|
553
|
-
char *ptr = RSTRING_PTR(source);
|
573
|
+
const char *ptr = RSTRING_PTR(source);
|
554
574
|
long len = RSTRING_LEN(source);
|
555
575
|
if (len < 2) {
|
556
576
|
rb_raise(eParserError, "A JSON text must at least contain two octets!");
|
557
577
|
}
|
558
578
|
#ifdef HAVE_RUBY_ENCODING_H
|
559
579
|
{
|
560
|
-
|
561
|
-
if (
|
580
|
+
rb_encoding *enc = rb_enc_get(source);
|
581
|
+
if (enc == rb_ascii8bit_encoding()) {
|
562
582
|
if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
|
563
|
-
source =
|
583
|
+
source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
|
564
584
|
} else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
|
565
|
-
source =
|
585
|
+
source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
|
566
586
|
} else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
|
567
|
-
source =
|
587
|
+
source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
|
568
588
|
} else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
|
569
|
-
source =
|
589
|
+
source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
|
570
590
|
} else {
|
571
591
|
source = rb_str_dup(source);
|
572
592
|
FORCE_UTF8(source);
|
573
593
|
}
|
574
594
|
} else {
|
575
|
-
source =
|
595
|
+
source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
|
576
596
|
}
|
577
597
|
}
|
578
598
|
#else
|
@@ -610,8 +630,8 @@ static VALUE convert_encoding(VALUE source)
|
|
610
630
|
* (keys) in a JSON object. Otherwise strings are returned, which is also
|
611
631
|
* the default.
|
612
632
|
* * *create_additions*: If set to false, the Parser doesn't create
|
613
|
-
* additions even if a
|
614
|
-
* defaults to
|
633
|
+
* additions even if a matching class and create_id was found. This option
|
634
|
+
* defaults to false.
|
615
635
|
* * *object_class*: Defaults to Hash
|
616
636
|
* * *array_class*: Defaults to Array
|
617
637
|
*/
|
@@ -623,12 +643,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
623
643
|
if (json->Vsource) {
|
624
644
|
rb_raise(rb_eTypeError, "already initialized instance");
|
625
645
|
}
|
646
|
+
#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
647
|
+
rb_scan_args(argc, argv, "1:", &source, &opts);
|
648
|
+
#else
|
626
649
|
rb_scan_args(argc, argv, "11", &source, &opts);
|
650
|
+
#endif
|
627
651
|
if (!NIL_P(opts)) {
|
652
|
+
#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
628
653
|
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
629
654
|
if (NIL_P(opts)) {
|
630
655
|
rb_raise(rb_eArgError, "opts needs to be like a hash");
|
631
656
|
} else {
|
657
|
+
#endif
|
632
658
|
VALUE tmp = ID2SYM(i_max_nesting);
|
633
659
|
if (option_given_p(opts, tmp)) {
|
634
660
|
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
@@ -691,7 +717,9 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
691
717
|
} else {
|
692
718
|
json->match_string = Qnil;
|
693
719
|
}
|
720
|
+
#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
|
694
721
|
}
|
722
|
+
#endif
|
695
723
|
} else {
|
696
724
|
json->max_nesting = 100;
|
697
725
|
json->allow_nan = 0;
|
@@ -700,12 +728,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
700
728
|
json->object_class = Qnil;
|
701
729
|
json->array_class = Qnil;
|
702
730
|
}
|
703
|
-
|
731
|
+
StringValue(source);
|
704
732
|
if (!json->quirks_mode) {
|
705
|
-
|
733
|
+
source = convert_encoding(source);
|
706
734
|
}
|
707
735
|
json->current_nesting = 0;
|
708
|
-
StringValue(source);
|
709
736
|
json->len = RSTRING_LEN(source);
|
710
737
|
json->source = RSTRING_PTR(source);;
|
711
738
|
json->Vsource = source;
|
@@ -754,7 +781,7 @@ static VALUE cParser_parse_strict(VALUE self)
|
|
754
781
|
if (cs >= JSON_first_final && p == pe) {
|
755
782
|
return result;
|
756
783
|
} else {
|
757
|
-
|
784
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
758
785
|
return Qnil;
|
759
786
|
}
|
760
787
|
}
|
@@ -792,7 +819,7 @@ static VALUE cParser_parse_quirks_mode(VALUE self)
|
|
792
819
|
if (cs >= JSON_quirks_mode_first_final && p == pe) {
|
793
820
|
return result;
|
794
821
|
} else {
|
795
|
-
|
822
|
+
rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
796
823
|
return Qnil;
|
797
824
|
}
|
798
825
|
}
|
@@ -814,17 +841,9 @@ static VALUE cParser_parse(VALUE self)
|
|
814
841
|
}
|
815
842
|
}
|
816
843
|
|
817
|
-
|
818
|
-
static JSON_Parser *JSON_allocate()
|
819
|
-
{
|
820
|
-
JSON_Parser *json = ALLOC(JSON_Parser);
|
821
|
-
MEMZERO(json, JSON_Parser, 1);
|
822
|
-
json->fbuffer = fbuffer_alloc(0);
|
823
|
-
return json;
|
824
|
-
}
|
825
|
-
|
826
|
-
static void JSON_mark(JSON_Parser *json)
|
844
|
+
static void JSON_mark(void *ptr)
|
827
845
|
{
|
846
|
+
JSON_Parser *json = ptr;
|
828
847
|
rb_gc_mark_maybe(json->Vsource);
|
829
848
|
rb_gc_mark_maybe(json->create_id);
|
830
849
|
rb_gc_mark_maybe(json->object_class);
|
@@ -832,16 +851,36 @@ static void JSON_mark(JSON_Parser *json)
|
|
832
851
|
rb_gc_mark_maybe(json->match_string);
|
833
852
|
}
|
834
853
|
|
835
|
-
static void JSON_free(
|
854
|
+
static void JSON_free(void *ptr)
|
836
855
|
{
|
856
|
+
JSON_Parser *json = ptr;
|
837
857
|
fbuffer_free(json->fbuffer);
|
838
858
|
ruby_xfree(json);
|
839
859
|
}
|
840
860
|
|
861
|
+
static size_t JSON_memsize(const void *ptr)
|
862
|
+
{
|
863
|
+
const JSON_Parser *json = ptr;
|
864
|
+
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
|
865
|
+
}
|
866
|
+
|
867
|
+
#ifdef NEW_TYPEDDATA_WRAPPER
|
868
|
+
static const rb_data_type_t JSON_Parser_type = {
|
869
|
+
"JSON/Parser",
|
870
|
+
{JSON_mark, JSON_free, JSON_memsize,},
|
871
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
872
|
+
0, 0,
|
873
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
874
|
+
#endif
|
875
|
+
};
|
876
|
+
#endif
|
877
|
+
|
841
878
|
static VALUE cJSON_parser_s_allocate(VALUE klass)
|
842
879
|
{
|
843
|
-
JSON_Parser *json
|
844
|
-
|
880
|
+
JSON_Parser *json;
|
881
|
+
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
|
882
|
+
json->fbuffer = fbuffer_alloc(0);
|
883
|
+
return obj;
|
845
884
|
}
|
846
885
|
|
847
886
|
/*
|
@@ -868,7 +907,7 @@ static VALUE cParser_quirks_mode_p(VALUE self)
|
|
868
907
|
}
|
869
908
|
|
870
909
|
|
871
|
-
void Init_parser()
|
910
|
+
void Init_parser(void)
|
872
911
|
{
|
873
912
|
rb_require("json/common");
|
874
913
|
mJSON = rb_define_module("JSON");
|
@@ -905,14 +944,11 @@ void Init_parser()
|
|
905
944
|
i_aref = rb_intern("[]");
|
906
945
|
i_leftshift = rb_intern("<<");
|
907
946
|
#ifdef HAVE_RUBY_ENCODING_H
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
|
914
|
-
i_encoding = rb_intern("encoding");
|
915
|
-
i_encode = rb_intern("encode");
|
947
|
+
UTF_8 = rb_utf8_encoding();
|
948
|
+
UTF_16BE = rb_enc_find("utf-16be");
|
949
|
+
UTF_16LE = rb_enc_find("utf-16le");
|
950
|
+
UTF_32BE = rb_enc_find("utf-32be");
|
951
|
+
UTF_32LE = rb_enc_find("utf-32le");
|
916
952
|
#else
|
917
953
|
i_iconv = rb_intern("iconv");
|
918
954
|
#endif
|
data/ext/json/extconf.rb
ADDED
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -428,11 +427,14 @@ public final class Generator {
|
|
428
427
|
new Handler<IRubyObject>() {
|
429
428
|
@Override
|
430
429
|
RubyString generateNew(Session session, IRubyObject object) {
|
431
|
-
|
432
|
-
object.callMethod(session.getContext(), "to_json",
|
433
|
-
|
434
|
-
|
435
|
-
|
430
|
+
if (object.respondsTo("to_json")) {
|
431
|
+
IRubyObject result = object.callMethod(session.getContext(), "to_json",
|
432
|
+
new IRubyObject[] {session.getState()});
|
433
|
+
if (result instanceof RubyString) return (RubyString)result;
|
434
|
+
throw session.getRuntime().newTypeError("to_json must return a String");
|
435
|
+
} else {
|
436
|
+
return OBJECT_HANDLER.generateNew(session, object);
|
437
|
+
}
|
436
438
|
}
|
437
439
|
|
438
440
|
@Override
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|