json 1.8.6 → 2.3.0

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.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -5
  4. data/{CHANGES → CHANGES.md} +179 -95
  5. data/Gemfile +10 -3
  6. data/LICENSE +56 -0
  7. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  8. data/README.md +171 -107
  9. data/Rakefile +33 -22
  10. data/VERSION +1 -1
  11. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  12. data/ext/json/ext/generator/generator.c +105 -98
  13. data/ext/json/ext/generator/generator.h +0 -6
  14. data/ext/json/ext/parser/extconf.rb +3 -0
  15. data/ext/json/ext/parser/parser.c +376 -480
  16. data/ext/json/ext/parser/parser.h +4 -5
  17. data/ext/json/ext/parser/parser.rl +108 -175
  18. data/ext/json/extconf.rb +0 -1
  19. data/java/src/json/ext/Generator.java +35 -15
  20. data/java/src/json/ext/GeneratorState.java +2 -54
  21. data/java/src/json/ext/OptionsReader.java +1 -1
  22. data/java/src/json/ext/Parser.java +131 -413
  23. data/java/src/json/ext/Parser.rl +47 -122
  24. data/java/src/json/ext/RuntimeInfo.java +0 -4
  25. data/json-java.gemspec +1 -2
  26. data/json.gemspec +0 -0
  27. data/json_pure.gemspec +8 -7
  28. data/lib/json.rb +1 -0
  29. data/lib/json/add/bigdecimal.rb +3 -2
  30. data/lib/json/add/complex.rb +4 -3
  31. data/lib/json/add/core.rb +1 -0
  32. data/lib/json/add/date.rb +1 -1
  33. data/lib/json/add/date_time.rb +1 -1
  34. data/lib/json/add/exception.rb +1 -1
  35. data/lib/json/add/ostruct.rb +3 -3
  36. data/lib/json/add/range.rb +1 -1
  37. data/lib/json/add/rational.rb +3 -2
  38. data/lib/json/add/regexp.rb +3 -3
  39. data/lib/json/add/set.rb +29 -0
  40. data/lib/json/add/struct.rb +1 -1
  41. data/lib/json/add/symbol.rb +1 -1
  42. data/lib/json/add/time.rb +1 -1
  43. data/lib/json/common.rb +26 -54
  44. data/lib/json/ext.rb +0 -6
  45. data/lib/json/generic_object.rb +5 -4
  46. data/lib/json/pure.rb +2 -8
  47. data/lib/json/pure/generator.rb +53 -124
  48. data/lib/json/pure/parser.rb +41 -81
  49. data/lib/json/version.rb +2 -1
  50. data/references/rfc7159.txt +899 -0
  51. data/tests/fixtures/obsolete_fail1.json +1 -0
  52. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  53. data/tests/json_common_interface_test.rb +126 -0
  54. data/tests/json_encoding_test.rb +107 -0
  55. data/tests/json_ext_parser_test.rb +15 -0
  56. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
  57. data/tests/{test_json_generate.rb → json_generator_test.rb} +112 -39
  58. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  59. data/tests/json_parser_test.rb +472 -0
  60. data/tests/json_string_matching_test.rb +38 -0
  61. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  62. data/tools/fuzz.rb +1 -9
  63. metadata +22 -37
  64. data/TODO +0 -1
  65. data/data/example.json +0 -1
  66. data/data/index.html +0 -38
  67. data/data/prototype.js +0 -4184
  68. data/tests/fixtures/fail1.json +0 -1
  69. data/tests/test_json.rb +0 -519
  70. data/tests/test_json_encoding.rb +0 -65
  71. data/tests/test_json_string_matching.rb +0 -39
  72. data/tests/test_json_unicode.rb +0 -72
@@ -34,13 +34,12 @@ typedef struct JSON_ParserStruct {
34
34
  char *memo;
35
35
  VALUE create_id;
36
36
  int max_nesting;
37
- int current_nesting;
38
37
  int allow_nan;
39
38
  int parsing_name;
40
39
  int symbolize_names;
41
- int quirks_mode;
42
40
  VALUE object_class;
43
41
  VALUE array_class;
42
+ VALUE decimal_class;
44
43
  int create_additions;
45
44
  VALUE match_string;
46
45
  FBuffer *fbuffer;
@@ -58,11 +57,11 @@ typedef struct JSON_ParserStruct {
58
57
 
59
58
  static UTF32 unescape_unicode(const unsigned char *p);
60
59
  static int convert_UTF32_to_UTF8(char *buf, UTF32 ch);
61
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result);
62
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result);
60
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
61
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
63
62
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result);
64
63
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result);
65
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result);
64
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting);
66
65
  static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd);
67
66
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result);
68
67
  static VALUE convert_encoding(VALUE source);
@@ -2,7 +2,7 @@
2
2
  #include "parser.h"
3
3
 
4
4
  #if defined HAVE_RUBY_ENCODING_H
5
- # define EXC_ENCODING UTF_8,
5
+ # define EXC_ENCODING rb_utf8_encoding(),
6
6
  # ifndef HAVE_RB_ENC_RAISE
7
7
  static void
8
8
  enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
@@ -25,7 +25,7 @@ enc_raise(rb_encoding *enc, VALUE exc, const char *fmt, ...)
25
25
 
26
26
  /* unicode */
27
27
 
28
- static const char digit_values[256] = {
28
+ static const signed char digit_values[256] = {
29
29
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
30
30
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
31
31
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -44,7 +44,7 @@ static const char digit_values[256] = {
44
44
 
45
45
  static UTF32 unescape_unicode(const unsigned char *p)
46
46
  {
47
- char b;
47
+ signed char b;
48
48
  UTF32 result = 0;
49
49
  b = digit_values[p[0]];
50
50
  if (b < 0) return UNI_REPLACEMENT_CHAR;
@@ -87,19 +87,15 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
87
87
  return len;
88
88
  }
89
89
 
90
- #ifdef HAVE_RUBY_ENCODING_H
91
- static rb_encoding *UTF_8, *UTF_16BE, *UTF_16LE, *UTF_32BE, *UTF_32LE;
92
- #else
93
- static ID i_iconv;
94
- #endif
95
-
96
90
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
97
91
  static VALUE CNaN, CInfinity, CMinusInfinity;
92
+ static VALUE cBigDecimal = Qundef;
98
93
 
99
94
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
100
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
101
- i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
102
- i_match_string, i_aset, i_aref, i_leftshift;
95
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
96
+ i_object_class, i_array_class, i_decimal_class, i_key_p,
97
+ i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
98
+ i_leftshift, i_new, i_BigDecimal;
103
99
 
104
100
  %%{
105
101
  machine JSON_common;
@@ -137,7 +133,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
137
133
 
138
134
  action parse_value {
139
135
  VALUE v = Qnil;
140
- char *np = JSON_parse_value(json, fpc, pe, &v);
136
+ char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
141
137
  if (np == NULL) {
142
138
  fhold; fbreak;
143
139
  } else {
@@ -170,14 +166,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
170
166
  ) @exit;
171
167
  }%%
172
168
 
173
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
169
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
174
170
  {
175
171
  int cs = EVIL;
176
172
  VALUE last_name = Qnil;
177
173
  VALUE object_class = json->object_class;
178
174
 
179
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
180
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
175
+ if (json->max_nesting && current_nesting > json->max_nesting) {
176
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
181
177
  }
182
178
 
183
179
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
@@ -243,7 +239,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
243
239
 
244
240
  action parse_number {
245
241
  char *np;
246
- if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
242
+ if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
247
243
  if (json->allow_nan) {
248
244
  *result = CMinusInfinity;
249
245
  fexec p + 10;
@@ -261,23 +257,19 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
261
257
 
262
258
  action parse_array {
263
259
  char *np;
264
- json->current_nesting++;
265
- np = JSON_parse_array(json, fpc, pe, result);
266
- json->current_nesting--;
260
+ np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
267
261
  if (np == NULL) { fhold; fbreak; } else fexec np;
268
262
  }
269
263
 
270
264
  action parse_object {
271
265
  char *np;
272
- json->current_nesting++;
273
- np = JSON_parse_object(json, fpc, pe, result);
274
- json->current_nesting--;
266
+ np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
275
267
  if (np == NULL) { fhold; fbreak; } else fexec np;
276
268
  }
277
269
 
278
270
  action exit { fhold; fbreak; }
279
271
 
280
- main := (
272
+ main := ignore* (
281
273
  Vnull @parse_null |
282
274
  Vfalse @parse_false |
283
275
  Vtrue @parse_true |
@@ -287,10 +279,10 @@ main := (
287
279
  begin_string >parse_string |
288
280
  begin_array >parse_array |
289
281
  begin_object >parse_object
290
- ) %*exit;
282
+ ) ignore* %*exit;
291
283
  }%%
292
284
 
293
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
285
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
294
286
  {
295
287
  int cs = EVIL;
296
288
 
@@ -348,6 +340,19 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
348
340
  ) (^[0-9Ee.\-]? @exit );
349
341
  }%%
350
342
 
343
+ static int is_bigdecimal_class(VALUE obj)
344
+ {
345
+ if (cBigDecimal == Qundef) {
346
+ if (rb_const_defined(rb_cObject, i_BigDecimal)) {
347
+ cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
348
+ }
349
+ else {
350
+ return 0;
351
+ }
352
+ }
353
+ return obj == cBigDecimal;
354
+ }
355
+
351
356
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
352
357
  {
353
358
  int cs = EVIL;
@@ -361,7 +366,17 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
361
366
  fbuffer_clear(json->fbuffer);
362
367
  fbuffer_append(json->fbuffer, json->memo, len);
363
368
  fbuffer_append_char(json->fbuffer, '\0');
364
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
369
+ if (NIL_P(json->decimal_class)) {
370
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
371
+ } else {
372
+ VALUE text;
373
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
374
+ if (is_bigdecimal_class(json->decimal_class)) {
375
+ *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
376
+ } else {
377
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
378
+ }
379
+ }
365
380
  return p + 1;
366
381
  } else {
367
382
  return NULL;
@@ -377,7 +392,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
377
392
 
378
393
  action parse_value {
379
394
  VALUE v = Qnil;
380
- char *np = JSON_parse_value(json, fpc, pe, &v);
395
+ char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
381
396
  if (np == NULL) {
382
397
  fhold; fbreak;
383
398
  } else {
@@ -400,13 +415,13 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
400
415
  end_array @exit;
401
416
  }%%
402
417
 
403
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
418
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
404
419
  {
405
420
  int cs = EVIL;
406
421
  VALUE array_class = json->array_class;
407
422
 
408
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
409
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
423
+ if (json->max_nesting && current_nesting > json->max_nesting) {
424
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
410
425
  }
411
426
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
412
427
 
@@ -456,13 +471,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
456
471
  break;
457
472
  case 'u':
458
473
  if (pe > stringEnd - 4) {
459
- return Qnil;
474
+ rb_enc_raise(
475
+ EXC_ENCODING eParserError,
476
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
477
+ );
460
478
  } else {
461
479
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
462
480
  pe += 3;
463
481
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
464
482
  pe++;
465
- if (pe > stringEnd - 6) return Qnil;
483
+ if (pe > stringEnd - 6) {
484
+ rb_enc_raise(
485
+ EXC_ENCODING eParserError,
486
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
487
+ );
488
+ }
466
489
  if (pe[0] == '\\' && pe[1] == 'u') {
467
490
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
468
491
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -548,6 +571,8 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
548
571
 
549
572
  if (json->symbolize_names && json->parsing_name) {
550
573
  *result = rb_str_intern(*result);
574
+ } else if (RB_TYPE_P(*result, T_STRING)) {
575
+ rb_str_resize(*result, RSTRING_LEN(*result));
551
576
  }
552
577
  if (cs >= JSON_string_first_final) {
553
578
  return p + 1;
@@ -570,41 +595,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
570
595
 
571
596
  static VALUE convert_encoding(VALUE source)
572
597
  {
573
- const char *ptr = RSTRING_PTR(source);
574
- long len = RSTRING_LEN(source);
575
- if (len < 2) {
576
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
577
- }
578
598
  #ifdef HAVE_RUBY_ENCODING_H
579
- {
580
- rb_encoding *enc = rb_enc_get(source);
581
- if (enc == rb_ascii8bit_encoding()) {
582
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
583
- source = rb_str_conv_enc(source, UTF_32BE, rb_utf8_encoding());
584
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
585
- source = rb_str_conv_enc(source, UTF_16BE, rb_utf8_encoding());
586
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
587
- source = rb_str_conv_enc(source, UTF_32LE, rb_utf8_encoding());
588
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
589
- source = rb_str_conv_enc(source, UTF_16LE, rb_utf8_encoding());
590
- } else {
591
- source = rb_str_dup(source);
592
- FORCE_UTF8(source);
593
- }
594
- } else {
595
- source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
596
- }
597
- }
598
- #else
599
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
600
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
601
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
602
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
603
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
604
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
605
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
606
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
599
+ rb_encoding *enc = rb_enc_get(source);
600
+ if (enc == rb_ascii8bit_encoding()) {
601
+ if (OBJ_FROZEN(source)) {
602
+ source = rb_str_dup(source);
607
603
  }
604
+ FORCE_UTF8(source);
605
+ } else {
606
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
607
+ }
608
608
  #endif
609
609
  return source;
610
610
  }
@@ -627,8 +627,9 @@ static VALUE convert_encoding(VALUE source)
627
627
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
628
628
  * false.
629
629
  * * *symbolize_names*: If set to true, returns symbols for the names
630
- * (keys) in a JSON object. Otherwise strings are returned, which is also
631
- * the default.
630
+ * (keys) in a JSON object. Otherwise strings are returned, which is
631
+ * also the default. It's not possible to use this option in
632
+ * conjunction with the *create_additions* option.
632
633
  * * *create_additions*: If set to false, the Parser doesn't create
633
634
  * additions even if a matching class and create_id was found. This option
634
635
  * defaults to false.
@@ -679,19 +680,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
679
680
  } else {
680
681
  json->symbolize_names = 0;
681
682
  }
682
- tmp = ID2SYM(i_quirks_mode);
683
- if (option_given_p(opts, tmp)) {
684
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
685
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
686
- } else {
687
- json->quirks_mode = 0;
688
- }
689
683
  tmp = ID2SYM(i_create_additions);
690
684
  if (option_given_p(opts, tmp)) {
691
685
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
692
686
  } else {
693
687
  json->create_additions = 0;
694
688
  }
689
+ if (json->symbolize_names && json->create_additions) {
690
+ rb_raise(rb_eArgError,
691
+ "options :symbolize_names and :create_additions cannot be "
692
+ " used in conjunction");
693
+ }
695
694
  tmp = ID2SYM(i_create_id);
696
695
  if (option_given_p(opts, tmp)) {
697
696
  json->create_id = rb_hash_aref(opts, tmp);
@@ -710,6 +709,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
710
709
  } else {
711
710
  json->array_class = Qnil;
712
711
  }
712
+ tmp = ID2SYM(i_decimal_class);
713
+ if (option_given_p(opts, tmp)) {
714
+ json->decimal_class = rb_hash_aref(opts, tmp);
715
+ } else {
716
+ json->decimal_class = Qnil;
717
+ }
713
718
  tmp = ID2SYM(i_match_string);
714
719
  if (option_given_p(opts, tmp)) {
715
720
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -723,16 +728,14 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
723
728
  } else {
724
729
  json->max_nesting = 100;
725
730
  json->allow_nan = 0;
726
- json->create_additions = 1;
731
+ json->create_additions = 0;
727
732
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
728
733
  json->object_class = Qnil;
729
734
  json->array_class = Qnil;
735
+ json->decimal_class = Qnil;
730
736
  }
737
+ source = convert_encoding(StringValue(source));
731
738
  StringValue(source);
732
- if (!json->quirks_mode) {
733
- source = convert_encoding(source);
734
- }
735
- json->current_nesting = 0;
736
739
  json->len = RSTRING_LEN(source);
737
740
  json->source = RSTRING_PTR(source);;
738
741
  json->Vsource = source;
@@ -746,56 +749,8 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
746
749
 
747
750
  include JSON_common;
748
751
 
749
- action parse_object {
750
- char *np;
751
- json->current_nesting = 1;
752
- np = JSON_parse_object(json, fpc, pe, &result);
753
- if (np == NULL) { fhold; fbreak; } else fexec np;
754
- }
755
-
756
- action parse_array {
757
- char *np;
758
- json->current_nesting = 1;
759
- np = JSON_parse_array(json, fpc, pe, &result);
760
- if (np == NULL) { fhold; fbreak; } else fexec np;
761
- }
762
-
763
- main := ignore* (
764
- begin_object >parse_object |
765
- begin_array >parse_array
766
- ) ignore*;
767
- }%%
768
-
769
- static VALUE cParser_parse_strict(VALUE self)
770
- {
771
- char *p, *pe;
772
- int cs = EVIL;
773
- VALUE result = Qnil;
774
- GET_PARSER;
775
-
776
- %% write init;
777
- p = json->source;
778
- pe = p + json->len;
779
- %% write exec;
780
-
781
- if (cs >= JSON_first_final && p == pe) {
782
- return result;
783
- } else {
784
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
785
- return Qnil;
786
- }
787
- }
788
-
789
-
790
- %%{
791
- machine JSON_quirks_mode;
792
-
793
- write data;
794
-
795
- include JSON_common;
796
-
797
752
  action parse_value {
798
- char *np = JSON_parse_value(json, fpc, pe, &result);
753
+ char *np = JSON_parse_value(json, fpc, pe, &result, 0);
799
754
  if (np == NULL) { fhold; fbreak; } else fexec np;
800
755
  }
801
756
 
@@ -804,26 +759,6 @@ static VALUE cParser_parse_strict(VALUE self)
804
759
  ) ignore*;
805
760
  }%%
806
761
 
807
- static VALUE cParser_parse_quirks_mode(VALUE self)
808
- {
809
- char *p, *pe;
810
- int cs = EVIL;
811
- VALUE result = Qnil;
812
- GET_PARSER;
813
-
814
- %% write init;
815
- p = json->source;
816
- pe = p + json->len;
817
- %% write exec;
818
-
819
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
820
- return result;
821
- } else {
822
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
823
- return Qnil;
824
- }
825
- }
826
-
827
762
  /*
828
763
  * call-seq: parse()
829
764
  *
@@ -832,12 +767,21 @@ static VALUE cParser_parse_quirks_mode(VALUE self)
832
767
  */
833
768
  static VALUE cParser_parse(VALUE self)
834
769
  {
770
+ char *p, *pe;
771
+ int cs = EVIL;
772
+ VALUE result = Qnil;
835
773
  GET_PARSER;
836
774
 
837
- if (json->quirks_mode) {
838
- return cParser_parse_quirks_mode(self);
775
+ %% write init;
776
+ p = json->source;
777
+ pe = p + json->len;
778
+ %% write exec;
779
+
780
+ if (cs >= JSON_first_final && p == pe) {
781
+ return result;
839
782
  } else {
840
- return cParser_parse_strict(self);
783
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
784
+ return Qnil;
841
785
  }
842
786
  }
843
787
 
@@ -848,6 +792,7 @@ static void JSON_mark(void *ptr)
848
792
  rb_gc_mark_maybe(json->create_id);
849
793
  rb_gc_mark_maybe(json->object_class);
850
794
  rb_gc_mark_maybe(json->array_class);
795
+ rb_gc_mark_maybe(json->decimal_class);
851
796
  rb_gc_mark_maybe(json->match_string);
852
797
  }
853
798
 
@@ -895,35 +840,30 @@ static VALUE cParser_source(VALUE self)
895
840
  return rb_str_dup(json->Vsource);
896
841
  }
897
842
 
898
- /*
899
- * call-seq: quirks_mode?()
900
- *
901
- * Returns a true, if this parser is in quirks_mode, false otherwise.
902
- */
903
- static VALUE cParser_quirks_mode_p(VALUE self)
904
- {
905
- GET_PARSER;
906
- return json->quirks_mode ? Qtrue : Qfalse;
907
- }
908
-
909
-
910
843
  void Init_parser(void)
911
844
  {
845
+ #undef rb_intern
912
846
  rb_require("json/common");
913
847
  mJSON = rb_define_module("JSON");
914
848
  mExt = rb_define_module_under(mJSON, "Ext");
915
849
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
916
850
  eParserError = rb_path2class("JSON::ParserError");
917
851
  eNestingError = rb_path2class("JSON::NestingError");
852
+ rb_gc_register_mark_object(eParserError);
853
+ rb_gc_register_mark_object(eNestingError);
918
854
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
919
855
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
920
856
  rb_define_method(cParser, "parse", cParser_parse, 0);
921
857
  rb_define_method(cParser, "source", cParser_source, 0);
922
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
923
858
 
924
859
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
860
+ rb_gc_register_mark_object(CNaN);
861
+
925
862
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
863
+ rb_gc_register_mark_object(CInfinity);
864
+
926
865
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
866
+ rb_gc_register_mark_object(CMinusInfinity);
927
867
 
928
868
  i_json_creatable_p = rb_intern("json_creatable?");
929
869
  i_json_create = rb_intern("json_create");
@@ -933,9 +873,9 @@ void Init_parser(void)
933
873
  i_max_nesting = rb_intern("max_nesting");
934
874
  i_allow_nan = rb_intern("allow_nan");
935
875
  i_symbolize_names = rb_intern("symbolize_names");
936
- i_quirks_mode = rb_intern("quirks_mode");
937
876
  i_object_class = rb_intern("object_class");
938
877
  i_array_class = rb_intern("array_class");
878
+ i_decimal_class = rb_intern("decimal_class");
939
879
  i_match = rb_intern("match");
940
880
  i_match_string = rb_intern("match_string");
941
881
  i_key_p = rb_intern("key?");
@@ -943,15 +883,8 @@ void Init_parser(void)
943
883
  i_aset = rb_intern("[]=");
944
884
  i_aref = rb_intern("[]");
945
885
  i_leftshift = rb_intern("<<");
946
- #ifdef HAVE_RUBY_ENCODING_H
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");
952
- #else
953
- i_iconv = rb_intern("iconv");
954
- #endif
886
+ i_new = rb_intern("new");
887
+ i_BigDecimal = rb_intern("BigDecimal");
955
888
  }
956
889
 
957
890
  /*