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.

Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.travis.yml +10 -12
  4. data/CHANGES +23 -0
  5. data/Gemfile +1 -5
  6. data/{README.rdoc → README.md} +34 -47
  7. data/Rakefile +10 -20
  8. data/VERSION +1 -1
  9. data/ext/json/ext/fbuffer/fbuffer.h +10 -1
  10. data/ext/json/ext/generator/extconf.rb +0 -10
  11. data/ext/json/ext/generator/generator.c +85 -28
  12. data/ext/json/ext/generator/generator.h +34 -5
  13. data/ext/json/ext/parser/extconf.rb +0 -10
  14. data/ext/json/ext/parser/parser.c +166 -130
  15. data/ext/json/ext/parser/parser.h +19 -4
  16. data/ext/json/ext/parser/parser.rl +84 -48
  17. data/ext/json/extconf.rb +3 -0
  18. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  19. data/java/src/json/ext/Generator.java +9 -7
  20. data/java/src/json/ext/GeneratorMethods.java +1 -2
  21. data/java/src/json/ext/GeneratorService.java +1 -2
  22. data/java/src/json/ext/GeneratorState.java +1 -2
  23. data/java/src/json/ext/OptionsReader.java +1 -2
  24. data/java/src/json/ext/Parser.java +87 -87
  25. data/java/src/json/ext/Parser.rl +7 -7
  26. data/java/src/json/ext/ParserService.java +1 -2
  27. data/java/src/json/ext/RuntimeInfo.java +1 -2
  28. data/java/src/json/ext/StringDecoder.java +1 -2
  29. data/java/src/json/ext/StringEncoder.java +5 -0
  30. data/java/src/json/ext/Utils.java +1 -2
  31. data/json-java.gemspec +16 -1
  32. data/json.gemspec +0 -0
  33. data/json_pure.gemspec +23 -26
  34. data/lib/json/add/complex.rb +7 -1
  35. data/lib/json/add/rational.rb +5 -0
  36. data/lib/json/add/time.rb +1 -1
  37. data/lib/json/common.rb +5 -5
  38. data/lib/json/pure/generator.rb +10 -2
  39. data/lib/json/version.rb +1 -1
  40. data/tests/test_json.rb +8 -34
  41. data/tests/test_json_generate.rb +34 -8
  42. data/tools/diff.sh +18 -0
  43. metadata +39 -39
  44. data/COPYING +0 -58
  45. data/COPYING-json-jruby +0 -57
  46. 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
- Data_Get_Struct(self, JSON_Parser, json)
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 JSON_Parser *JSON_allocate();
72
- static void JSON_mark(JSON_Parser *json);
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 VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
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
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
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
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
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
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
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
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
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
- VALUE encoding = rb_funcall(source, i_encoding, 0);
561
- if (encoding == CEncoding_ASCII_8BIT) {
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 = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
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 = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
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 = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
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 = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
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 = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
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 matchin class and create_id was found. This option
614
- * defaults to true.
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
- source = rb_convert_type(source, T_STRING, "String", "to_str");
731
+ StringValue(source);
704
732
  if (!json->quirks_mode) {
705
- source = convert_encoding(StringValue(source));
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
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
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
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
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(JSON_Parser *json)
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 = JSON_allocate();
844
- return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
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
- CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
909
- CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
910
- CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
911
- CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
912
- CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
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
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ create_makefile('json')
3
+
@@ -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 and GPLv2 licenses; see COPYING and GPL files
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 and GPLv2 licenses; see COPYING and GPL files
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
- IRubyObject result =
432
- object.callMethod(session.getContext(), "to_json",
433
- new IRubyObject[] {session.getState()});
434
- if (result instanceof RubyString) return (RubyString)result;
435
- throw session.getRuntime().newTypeError("to_json must return a String");
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 and GPLv2 licenses; see COPYING and GPL files
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 and GPLv2 licenses; see COPYING and GPL files
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 and GPLv2 licenses; see COPYING and GPL files
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 and GPLv2 licenses; see COPYING and GPL files
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