json 1.5.3 → 1.5.4

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.

@@ -9,7 +9,7 @@
9
9
 
10
10
  #ifdef HAVE_RUBY_ENCODING_H
11
11
  #include "ruby/encoding.h"
12
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
12
+ #define FORCE_UTF8(obj) ((obj) = rb_enc_associate(rb_str_dup(obj), rb_utf8_encoding()))
13
13
  #else
14
14
  #define FORCE_UTF8(obj)
15
15
  #endif
@@ -44,6 +44,7 @@ typedef struct JSON_ParserStruct {
44
44
  int allow_nan;
45
45
  int parsing_name;
46
46
  int symbolize_names;
47
+ int quirks_mode;
47
48
  VALUE object_class;
48
49
  VALUE array_class;
49
50
  int create_additions;
@@ -51,6 +52,9 @@ typedef struct JSON_ParserStruct {
51
52
  } JSON_Parser;
52
53
 
53
54
  #define GET_PARSER \
55
+ GET_PARSER_INIT; \
56
+ if (!json->Vsource) rb_raise(rb_eTypeError, "uninitialized instance")
57
+ #define GET_PARSER_INIT \
54
58
  JSON_Parser *json; \
55
59
  Data_Get_Struct(self, JSON_Parser, json)
56
60
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  /* unicode */
4
4
 
5
- static const char digit_values[256] = {
5
+ static const char digit_values[256] = {
6
6
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
7
7
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8
8
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -38,7 +38,7 @@ static UTF32 unescape_unicode(const unsigned char *p)
38
38
  return result;
39
39
  }
40
40
 
41
- static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
41
+ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
42
42
  {
43
43
  int len = 1;
44
44
  if (ch <= 0x7F) {
@@ -67,7 +67,7 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
67
67
  #ifdef HAVE_RUBY_ENCODING_H
68
68
  static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
69
69
  CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
70
- static ID i_encoding, i_encode, i_encode_bang, i_force_encoding;
70
+ static ID i_encoding, i_encode;
71
71
  #else
72
72
  static ID i_iconv;
73
73
  #endif
@@ -76,8 +76,9 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
76
76
  static VALUE CNaN, CInfinity, CMinusInfinity;
77
77
 
78
78
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
79
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
80
- i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_leftshift;
79
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
80
+ i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
81
+ i_match_string, i_aset, i_leftshift;
81
82
 
82
83
  %%{
83
84
  machine JSON_common;
@@ -97,7 +98,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
97
98
  VNaN = 'NaN';
98
99
  VInfinity = 'Infinity';
99
100
  VMinusInfinity = '-Infinity';
100
- begin_value = [nft"\-[{NI] | digit;
101
+ begin_value = [nft\"\-\[\{NI] | digit;
101
102
  begin_object = '{';
102
103
  end_object = '}';
103
104
  begin_array = '[';
@@ -115,14 +116,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
115
116
 
116
117
  action parse_value {
117
118
  VALUE v = Qnil;
118
- char *np = JSON_parse_value(json, fpc, pe, &v);
119
+ char *np = JSON_parse_value(json, fpc, pe, &v);
119
120
  if (np == NULL) {
120
121
  fhold; fbreak;
121
122
  } else {
122
123
  if (NIL_P(json->object_class)) {
123
- rb_hash_aset(*result, last_name, v);
124
+ rb_hash_aset(*result, last_name, v);
124
125
  } else {
125
- rb_funcall(*result, i_aset, 2, last_name, v);
126
+ rb_funcall(*result, i_aset, 2, last_name, v);
126
127
  }
127
128
  fexec np;
128
129
  }
@@ -138,13 +139,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
138
139
 
139
140
  action exit { fhold; fbreak; }
140
141
 
141
- a_pair = ignore* begin_name >parse_name
142
- ignore* name_separator ignore*
143
- begin_value >parse_value;
142
+ pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
143
+ next_pair = ignore* value_separator pair;
144
144
 
145
- main := begin_object
146
- (a_pair (ignore* value_separator a_pair)*)?
147
- ignore* end_object @exit;
145
+ main := (
146
+ begin_object
147
+ (pair (next_pair)*)? ignore*
148
+ end_object
149
+ ) @exit;
148
150
  }%%
149
151
 
150
152
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -178,6 +180,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
178
180
  }
179
181
  }
180
182
 
183
+
181
184
  %%{
182
185
  machine JSON_value;
183
186
  include JSON_common;
@@ -214,7 +217,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
214
217
 
215
218
  action parse_number {
216
219
  char *np;
217
- if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
220
+ if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
218
221
  if (json->allow_nan) {
219
222
  *result = CMinusInfinity;
220
223
  fexec p + 10;
@@ -230,7 +233,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
230
233
  fhold; fbreak;
231
234
  }
232
235
 
233
- action parse_array {
236
+ action parse_array {
234
237
  char *np;
235
238
  json->current_nesting++;
236
239
  np = JSON_parse_array(json, fpc, pe, result);
@@ -238,7 +241,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
238
241
  if (np == NULL) { fhold; fbreak; } else fexec np;
239
242
  }
240
243
 
241
- action parse_object {
244
+ action parse_object {
242
245
  char *np;
243
246
  json->current_nesting++;
244
247
  np = JSON_parse_object(json, fpc, pe, result);
@@ -282,7 +285,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
282
285
 
283
286
  action exit { fhold; fbreak; }
284
287
 
285
- main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
288
+ main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
286
289
  }%%
287
290
 
288
291
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -313,7 +316,7 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
313
316
  main := '-'? (
314
317
  (('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
315
318
  | (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
316
- ) (^[0-9Ee.\-] @exit );
319
+ ) (^[0-9Ee.\-]? @exit );
317
320
  }%%
318
321
 
319
322
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -342,7 +345,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
342
345
 
343
346
  action parse_value {
344
347
  VALUE v = Qnil;
345
- char *np = JSON_parse_value(json, fpc, pe, &v);
348
+ char *np = JSON_parse_value(json, fpc, pe, &v);
346
349
  if (np == NULL) {
347
350
  fhold; fbreak;
348
351
  } else {
@@ -419,7 +422,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
419
422
  unescape = (char *) "\f";
420
423
  break;
421
424
  case 'u':
422
- if (pe > stringEnd - 4) {
425
+ if (pe > stringEnd - 4) {
423
426
  return Qnil;
424
427
  } else {
425
428
  char buf[4];
@@ -475,7 +478,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
475
478
 
476
479
  action exit { fhold; fbreak; }
477
480
 
478
- main := '"' ((^(["\\] | 0..0x1f) | '\\'["\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^(["\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
481
+ main := '"' ((^([\"\\] | 0..0x1f) | '\\'[\"\\/bfnrt] | '\\u'[0-9a-fA-F]{4} | '\\'^([\"\\/bfnrtu]|0..0x1f))* %parse_string) '"' @exit;
479
482
  }%%
480
483
 
481
484
  static int
@@ -521,35 +524,7 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
521
524
  }
522
525
  }
523
526
 
524
-
525
- %%{
526
- machine JSON;
527
-
528
- write data;
529
-
530
- include JSON_common;
531
-
532
- action parse_object {
533
- char *np;
534
- json->current_nesting = 1;
535
- np = JSON_parse_object(json, fpc, pe, &result);
536
- if (np == NULL) { fhold; fbreak; } else fexec np;
537
- }
538
-
539
- action parse_array {
540
- char *np;
541
- json->current_nesting = 1;
542
- np = JSON_parse_array(json, fpc, pe, &result);
543
- if (np == NULL) { fhold; fbreak; } else fexec np;
544
- }
545
-
546
- main := ignore* (
547
- begin_object >parse_object |
548
- begin_array >parse_array
549
- ) ignore*;
550
- }%%
551
-
552
- /*
527
+ /*
553
528
  * Document-class: JSON::Ext::Parser
554
529
  *
555
530
  * This is the JSON parser implemented as a C extension. It can be configured
@@ -573,22 +548,15 @@ static VALUE convert_encoding(VALUE source)
573
548
  VALUE encoding = rb_funcall(source, i_encoding, 0);
574
549
  if (encoding == CEncoding_ASCII_8BIT) {
575
550
  if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
576
- source = rb_str_dup(source);
577
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32BE);
578
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
551
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
579
552
  } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
580
- source = rb_str_dup(source);
581
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16BE);
582
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
553
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
583
554
  } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
584
- source = rb_str_dup(source);
585
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_32LE);
586
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
555
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
587
556
  } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
588
- source = rb_str_dup(source);
589
- rb_funcall(source, i_force_encoding, 1, CEncoding_UTF_16LE);
590
- source = rb_funcall(source, i_encode_bang, 1, CEncoding_UTF_8);
557
+ source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
591
558
  } else {
559
+ source = rb_str_dup(source);
592
560
  FORCE_UTF8(source);
593
561
  }
594
562
  } else {
@@ -637,14 +605,13 @@ static VALUE convert_encoding(VALUE source)
637
605
  */
638
606
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
639
607
  {
640
- char *ptr;
641
- long len;
642
608
  VALUE source, opts;
643
- GET_PARSER;
609
+ GET_PARSER_INIT;
610
+
611
+ if (json->Vsource) {
612
+ rb_raise(rb_eTypeError, "already initialized instance");
613
+ }
644
614
  rb_scan_args(argc, argv, "11", &source, &opts);
645
- source = convert_encoding(StringValue(source));
646
- ptr = RSTRING_PTR(source);
647
- len = RSTRING_LEN(source);
648
615
  if (!NIL_P(opts)) {
649
616
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
650
617
  if (NIL_P(opts)) {
@@ -674,6 +641,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
674
641
  } else {
675
642
  json->symbolize_names = 0;
676
643
  }
644
+ tmp = ID2SYM(i_quirks_mode);
645
+ if (option_given_p(opts, tmp)) {
646
+ VALUE quirks_mode = rb_hash_aref(opts, tmp);
647
+ json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
648
+ } else {
649
+ json->quirks_mode = 0;
650
+ }
677
651
  tmp = ID2SYM(i_create_additions);
678
652
  if (option_given_p(opts, tmp)) {
679
653
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
@@ -714,20 +688,44 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
714
688
  json->object_class = Qnil;
715
689
  json->array_class = Qnil;
716
690
  }
691
+ if (!json->quirks_mode) {
692
+ source = convert_encoding(StringValue(source));
693
+ }
717
694
  json->current_nesting = 0;
718
- json->len = len;
719
- json->source = ptr;
695
+ json->len = RSTRING_LEN(source);
696
+ json->source = RSTRING_PTR(source);;
720
697
  json->Vsource = source;
721
698
  return self;
722
699
  }
723
700
 
724
- /*
725
- * call-seq: parse()
726
- *
727
- * Parses the current JSON text _source_ and returns the complete data
728
- * structure as a result.
729
- */
730
- static VALUE cParser_parse(VALUE self)
701
+ %%{
702
+ machine JSON;
703
+
704
+ write data;
705
+
706
+ include JSON_common;
707
+
708
+ action parse_object {
709
+ char *np;
710
+ json->current_nesting = 1;
711
+ np = JSON_parse_object(json, fpc, pe, &result);
712
+ if (np == NULL) { fhold; fbreak; } else fexec np;
713
+ }
714
+
715
+ action parse_array {
716
+ char *np;
717
+ json->current_nesting = 1;
718
+ np = JSON_parse_array(json, fpc, pe, &result);
719
+ if (np == NULL) { fhold; fbreak; } else fexec np;
720
+ }
721
+
722
+ main := ignore* (
723
+ begin_object >parse_object |
724
+ begin_array >parse_array
725
+ ) ignore*;
726
+ }%%
727
+
728
+ static VALUE cParser_parse_strict(VALUE self)
731
729
  {
732
730
  char *p, *pe;
733
731
  int cs = EVIL;
@@ -747,6 +745,62 @@ static VALUE cParser_parse(VALUE self)
747
745
  }
748
746
  }
749
747
 
748
+
749
+ %%{
750
+ machine JSON_quirks_mode;
751
+
752
+ write data;
753
+
754
+ include JSON_common;
755
+
756
+ action parse_value {
757
+ char *np = JSON_parse_value(json, fpc, pe, &result);
758
+ if (np == NULL) { fhold; fbreak; } else fexec np;
759
+ }
760
+
761
+ main := ignore* (
762
+ begin_value >parse_value
763
+ ) ignore*;
764
+ }%%
765
+
766
+ static VALUE cParser_parse_quirks_mode(VALUE self)
767
+ {
768
+ char *p, *pe;
769
+ int cs = EVIL;
770
+ VALUE result = Qnil;
771
+ GET_PARSER;
772
+
773
+ %% write init;
774
+ p = json->source;
775
+ pe = p + json->len;
776
+ %% write exec;
777
+
778
+ if (cs >= JSON_quirks_mode_first_final && p == pe) {
779
+ return result;
780
+ } else {
781
+ rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
782
+ return Qnil;
783
+ }
784
+ }
785
+
786
+ /*
787
+ * call-seq: parse()
788
+ *
789
+ * Parses the current JSON text _source_ and returns the complete data
790
+ * structure as a result.
791
+ */
792
+ static VALUE cParser_parse(VALUE self)
793
+ {
794
+ GET_PARSER;
795
+
796
+ if (json->quirks_mode) {
797
+ return cParser_parse_quirks_mode(self);
798
+ } else {
799
+ return cParser_parse_strict(self);
800
+ }
801
+ }
802
+
803
+
750
804
  static JSON_Parser *JSON_allocate()
751
805
  {
752
806
  JSON_Parser *json = ALLOC(JSON_Parser);
@@ -786,6 +840,18 @@ static VALUE cParser_source(VALUE self)
786
840
  return rb_str_dup(json->Vsource);
787
841
  }
788
842
 
843
+ /*
844
+ * call-seq: quirks_mode?()
845
+ *
846
+ * Returns a true, if this parser is in quirks_mode, false otherwise.
847
+ */
848
+ static VALUE cParser_quirks_mode_p(VALUE self)
849
+ {
850
+ GET_PARSER;
851
+ return json->quirks_mode ? Qtrue : Qfalse;
852
+ }
853
+
854
+
789
855
  void Init_parser()
790
856
  {
791
857
  rb_require("json/common");
@@ -798,6 +864,7 @@ void Init_parser()
798
864
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
799
865
  rb_define_method(cParser, "parse", cParser_parse, 0);
800
866
  rb_define_method(cParser, "source", cParser_source, 0);
867
+ rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
801
868
 
802
869
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
803
870
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
@@ -811,6 +878,7 @@ void Init_parser()
811
878
  i_max_nesting = rb_intern("max_nesting");
812
879
  i_allow_nan = rb_intern("allow_nan");
813
880
  i_symbolize_names = rb_intern("symbolize_names");
881
+ i_quirks_mode = rb_intern("quirks_mode");
814
882
  i_object_class = rb_intern("object_class");
815
883
  i_array_class = rb_intern("array_class");
816
884
  i_match = rb_intern("match");
@@ -828,9 +896,15 @@ void Init_parser()
828
896
  CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
829
897
  i_encoding = rb_intern("encoding");
830
898
  i_encode = rb_intern("encode");
831
- i_encode_bang = rb_intern("encode!");
832
- i_force_encoding = rb_intern("force_encoding");
833
899
  #else
834
900
  i_iconv = rb_intern("iconv");
835
901
  #endif
836
902
  }
903
+
904
+ /*
905
+ * Local variables:
906
+ * mode: c
907
+ * c-file-style: ruby
908
+ * indent-tabs-mode: nil
909
+ * End:
910
+ */
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
- *
3
+ *
4
4
  * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
5
  * for details.
6
6
  */
@@ -85,11 +85,11 @@ public final class Generator {
85
85
  /**
86
86
  * A class that concentrates all the information that is shared by
87
87
  * generators working on a single session.
88
- *
88
+ *
89
89
  * <p>A session is defined as the process of serializing a single root
90
90
  * object; any handler directly called by container handlers (arrays and
91
91
  * hashes/objects) shares this object with its caller.
92
- *
92
+ *
93
93
  * <p>Note that anything called indirectly (via {@link GENERIC_HANDLER})
94
94
  * won't be part of the session.
95
95
  */
@@ -376,9 +376,9 @@ public final class Generator {
376
376
  RubyString src;
377
377
 
378
378
  if (info.encodingsSupported() &&
379
- object.encoding(session.getContext()) != info.utf8) {
379
+ object.encoding(session.getContext()) != info.utf8.get()) {
380
380
  src = (RubyString)object.encode(session.getContext(),
381
- info.utf8);
381
+ info.utf8.get());
382
382
  } else {
383
383
  src = object;
384
384
  }