json 1.8.6 → 2.6.1

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 (107) hide show
  1. checksums.yaml +5 -5
  2. data/{CHANGES → CHANGES.md} +248 -98
  3. data/LICENSE +56 -0
  4. data/README.md +188 -108
  5. data/VERSION +1 -1
  6. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  7. data/ext/json/ext/generator/generator.c +227 -111
  8. data/ext/json/ext/generator/generator.h +5 -8
  9. data/ext/json/ext/parser/extconf.rb +29 -0
  10. data/ext/json/ext/parser/parser.c +3013 -1915
  11. data/ext/json/ext/parser/parser.h +10 -6
  12. data/ext/json/ext/parser/parser.rl +197 -183
  13. data/ext/json/extconf.rb +1 -1
  14. data/json.gemspec +0 -0
  15. data/lib/json/add/bigdecimal.rb +3 -2
  16. data/lib/json/add/complex.rb +4 -4
  17. data/lib/json/add/core.rb +1 -0
  18. data/lib/json/add/date.rb +1 -1
  19. data/lib/json/add/date_time.rb +1 -1
  20. data/lib/json/add/exception.rb +1 -1
  21. data/lib/json/add/ostruct.rb +3 -3
  22. data/lib/json/add/range.rb +1 -1
  23. data/lib/json/add/rational.rb +3 -3
  24. data/lib/json/add/regexp.rb +3 -3
  25. data/lib/json/add/set.rb +29 -0
  26. data/lib/json/add/struct.rb +1 -1
  27. data/lib/json/add/symbol.rb +1 -1
  28. data/lib/json/add/time.rb +1 -1
  29. data/lib/json/common.rb +381 -162
  30. data/lib/json/ext.rb +0 -6
  31. data/lib/json/generic_object.rb +5 -4
  32. data/lib/json/pure/generator.rb +73 -124
  33. data/lib/json/pure/parser.rb +63 -85
  34. data/lib/json/pure.rb +2 -8
  35. data/lib/json/version.rb +2 -1
  36. data/lib/json.rb +550 -29
  37. metadata +20 -127
  38. data/.gitignore +0 -17
  39. data/.travis.yml +0 -18
  40. data/Gemfile +0 -7
  41. data/README-json-jruby.markdown +0 -33
  42. data/Rakefile +0 -402
  43. data/TODO +0 -1
  44. data/data/example.json +0 -1
  45. data/data/index.html +0 -38
  46. data/data/prototype.js +0 -4184
  47. data/diagrams/.keep +0 -0
  48. data/install.rb +0 -23
  49. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  50. data/java/src/json/ext/Generator.java +0 -446
  51. data/java/src/json/ext/GeneratorMethods.java +0 -231
  52. data/java/src/json/ext/GeneratorService.java +0 -42
  53. data/java/src/json/ext/GeneratorState.java +0 -542
  54. data/java/src/json/ext/OptionsReader.java +0 -113
  55. data/java/src/json/ext/Parser.java +0 -2644
  56. data/java/src/json/ext/Parser.rl +0 -968
  57. data/java/src/json/ext/ParserService.java +0 -34
  58. data/java/src/json/ext/RuntimeInfo.java +0 -120
  59. data/java/src/json/ext/StringDecoder.java +0 -166
  60. data/java/src/json/ext/StringEncoder.java +0 -111
  61. data/java/src/json/ext/Utils.java +0 -88
  62. data/json-java.gemspec +0 -38
  63. data/json_pure.gemspec +0 -37
  64. data/lib/json/ext/.keep +0 -0
  65. data/tests/fixtures/fail1.json +0 -1
  66. data/tests/fixtures/fail10.json +0 -1
  67. data/tests/fixtures/fail11.json +0 -1
  68. data/tests/fixtures/fail12.json +0 -1
  69. data/tests/fixtures/fail13.json +0 -1
  70. data/tests/fixtures/fail14.json +0 -1
  71. data/tests/fixtures/fail18.json +0 -1
  72. data/tests/fixtures/fail19.json +0 -1
  73. data/tests/fixtures/fail2.json +0 -1
  74. data/tests/fixtures/fail20.json +0 -1
  75. data/tests/fixtures/fail21.json +0 -1
  76. data/tests/fixtures/fail22.json +0 -1
  77. data/tests/fixtures/fail23.json +0 -1
  78. data/tests/fixtures/fail24.json +0 -1
  79. data/tests/fixtures/fail25.json +0 -1
  80. data/tests/fixtures/fail27.json +0 -2
  81. data/tests/fixtures/fail28.json +0 -2
  82. data/tests/fixtures/fail3.json +0 -1
  83. data/tests/fixtures/fail4.json +0 -1
  84. data/tests/fixtures/fail5.json +0 -1
  85. data/tests/fixtures/fail6.json +0 -1
  86. data/tests/fixtures/fail7.json +0 -1
  87. data/tests/fixtures/fail8.json +0 -1
  88. data/tests/fixtures/fail9.json +0 -1
  89. data/tests/fixtures/pass1.json +0 -56
  90. data/tests/fixtures/pass15.json +0 -1
  91. data/tests/fixtures/pass16.json +0 -1
  92. data/tests/fixtures/pass17.json +0 -1
  93. data/tests/fixtures/pass2.json +0 -1
  94. data/tests/fixtures/pass26.json +0 -1
  95. data/tests/fixtures/pass3.json +0 -6
  96. data/tests/setup_variant.rb +0 -11
  97. data/tests/test_json.rb +0 -519
  98. data/tests/test_json_addition.rb +0 -196
  99. data/tests/test_json_encoding.rb +0 -65
  100. data/tests/test_json_fixtures.rb +0 -35
  101. data/tests/test_json_generate.rb +0 -348
  102. data/tests/test_json_generic_object.rb +0 -75
  103. data/tests/test_json_string_matching.rb +0 -39
  104. data/tests/test_json_unicode.rb +0 -72
  105. data/tools/diff.sh +0 -18
  106. data/tools/fuzz.rb +0 -139
  107. data/tools/server.rb +0 -62
@@ -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,14 @@ 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;
98
92
 
99
93
  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;
94
+ i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
95
+ i_object_class, i_array_class, i_decimal_class, i_key_p,
96
+ i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
97
+ i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
103
98
 
104
99
  %%{
105
100
  machine JSON_common;
@@ -137,11 +132,12 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
137
132
 
138
133
  action parse_value {
139
134
  VALUE v = Qnil;
140
- char *np = JSON_parse_value(json, fpc, pe, &v);
135
+ char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
141
136
  if (np == NULL) {
142
137
  fhold; fbreak;
143
138
  } else {
144
139
  if (NIL_P(json->object_class)) {
140
+ OBJ_FREEZE(last_name);
145
141
  rb_hash_aset(*result, last_name, v);
146
142
  } else {
147
143
  rb_funcall(*result, i_aset, 2, last_name, v);
@@ -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,16 +279,20 @@ 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
 
297
289
  %% write init;
298
290
  %% write exec;
299
291
 
292
+ if (json->freeze) {
293
+ OBJ_FREEZE(*result);
294
+ }
295
+
300
296
  if (cs >= JSON_value_first_final) {
301
297
  return p;
302
298
  } else {
@@ -357,11 +353,46 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
357
353
  %% write exec;
358
354
 
359
355
  if (cs >= JSON_float_first_final) {
356
+ VALUE mod = Qnil;
357
+ ID method_id = 0;
358
+ if (rb_respond_to(json->decimal_class, i_try_convert)) {
359
+ mod = json->decimal_class;
360
+ method_id = i_try_convert;
361
+ } else if (rb_respond_to(json->decimal_class, i_new)) {
362
+ mod = json->decimal_class;
363
+ method_id = i_new;
364
+ } else if (RB_TYPE_P(json->decimal_class, T_CLASS)) {
365
+ VALUE name = rb_class_name(json->decimal_class);
366
+ const char *name_cstr = RSTRING_PTR(name);
367
+ const char *last_colon = strrchr(name_cstr, ':');
368
+ if (last_colon) {
369
+ const char *mod_path_end = last_colon - 1;
370
+ VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr);
371
+ mod = rb_path_to_class(mod_path);
372
+
373
+ const char *method_name_beg = last_colon + 1;
374
+ long before_len = method_name_beg - name_cstr;
375
+ long len = RSTRING_LEN(name) - before_len;
376
+ VALUE method_name = rb_str_substr(name, before_len, len);
377
+ method_id = SYM2ID(rb_str_intern(method_name));
378
+ } else {
379
+ mod = rb_mKernel;
380
+ method_id = SYM2ID(rb_str_intern(name));
381
+ }
382
+ }
383
+
360
384
  long len = p - json->memo;
361
385
  fbuffer_clear(json->fbuffer);
362
386
  fbuffer_append(json->fbuffer, json->memo, len);
363
387
  fbuffer_append_char(json->fbuffer, '\0');
364
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
388
+
389
+ if (method_id) {
390
+ VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
391
+ *result = rb_funcallv(mod, method_id, 1, &text);
392
+ } else {
393
+ *result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
394
+ }
395
+
365
396
  return p + 1;
366
397
  } else {
367
398
  return NULL;
@@ -377,7 +408,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
377
408
 
378
409
  action parse_value {
379
410
  VALUE v = Qnil;
380
- char *np = JSON_parse_value(json, fpc, pe, &v);
411
+ char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
381
412
  if (np == NULL) {
382
413
  fhold; fbreak;
383
414
  } else {
@@ -400,13 +431,13 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
400
431
  end_array @exit;
401
432
  }%%
402
433
 
403
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
434
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
404
435
  {
405
436
  int cs = EVIL;
406
437
  VALUE array_class = json->array_class;
407
438
 
408
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
409
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
439
+ if (json->max_nesting && current_nesting > json->max_nesting) {
440
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
410
441
  }
411
442
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
412
443
 
@@ -421,17 +452,29 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
421
452
  }
422
453
  }
423
454
 
424
- static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
455
+ static const size_t MAX_STACK_BUFFER_SIZE = 128;
456
+ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int symbolize)
425
457
  {
426
- char *p = string, *pe = string, *unescape;
458
+ VALUE result = Qnil;
459
+ size_t bufferSize = stringEnd - string;
460
+ char *p = string, *pe = string, *unescape, *bufferStart, *buffer;
427
461
  int unescape_len;
428
462
  char buf[4];
429
463
 
464
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
465
+ bufferStart = buffer = ALLOC_N(char, bufferSize);
466
+ } else {
467
+ bufferStart = buffer = ALLOCA_N(char, bufferSize);
468
+ }
469
+
430
470
  while (pe < stringEnd) {
431
471
  if (*pe == '\\') {
432
472
  unescape = (char *) "?";
433
473
  unescape_len = 1;
434
- if (pe > p) rb_str_buf_cat(result, p, pe - p);
474
+ if (pe > p) {
475
+ MEMCPY(buffer, p, char, pe - p);
476
+ buffer += pe - p;
477
+ }
435
478
  switch (*++pe) {
436
479
  case 'n':
437
480
  unescape = (char *) "\n";
@@ -456,13 +499,27 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
456
499
  break;
457
500
  case 'u':
458
501
  if (pe > stringEnd - 4) {
459
- return Qnil;
502
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
503
+ free(bufferStart);
504
+ }
505
+ rb_enc_raise(
506
+ EXC_ENCODING eParserError,
507
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
508
+ );
460
509
  } else {
461
510
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
462
511
  pe += 3;
463
512
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
464
513
  pe++;
465
- if (pe > stringEnd - 6) return Qnil;
514
+ if (pe > stringEnd - 6) {
515
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
516
+ free(bufferStart);
517
+ }
518
+ rb_enc_raise(
519
+ EXC_ENCODING eParserError,
520
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
521
+ );
522
+ }
466
523
  if (pe[0] == '\\' && pe[1] == 'u') {
467
524
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
468
525
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -481,13 +538,55 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
481
538
  p = pe;
482
539
  continue;
483
540
  }
484
- rb_str_buf_cat(result, unescape, unescape_len);
541
+ MEMCPY(buffer, unescape, char, unescape_len);
542
+ buffer += unescape_len;
485
543
  p = ++pe;
486
544
  } else {
487
545
  pe++;
488
546
  }
489
547
  }
490
- rb_str_buf_cat(result, p, pe - p);
548
+
549
+ if (pe > p) {
550
+ MEMCPY(buffer, p, char, pe - p);
551
+ buffer += pe - p;
552
+ }
553
+
554
+ # ifdef HAVE_RB_ENC_INTERNED_STR
555
+ if (intern) {
556
+ result = rb_enc_interned_str(bufferStart, (long)(buffer - bufferStart), rb_utf8_encoding());
557
+ } else {
558
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
559
+ }
560
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
561
+ free(bufferStart);
562
+ }
563
+ # else
564
+ result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
565
+
566
+ if (bufferSize > MAX_STACK_BUFFER_SIZE) {
567
+ free(bufferStart);
568
+ }
569
+
570
+ if (intern) {
571
+ # if STR_UMINUS_DEDUPE_FROZEN
572
+ // Starting from MRI 2.8 it is preferable to freeze the string
573
+ // before deduplication so that it can be interned directly
574
+ // otherwise it would be duplicated first which is wasteful.
575
+ result = rb_funcall(rb_str_freeze(result), i_uminus, 0);
576
+ # elif STR_UMINUS_DEDUPE
577
+ // MRI 2.5 and older do not deduplicate strings that are already
578
+ // frozen.
579
+ result = rb_funcall(result, i_uminus, 0);
580
+ # else
581
+ result = rb_str_freeze(result);
582
+ # endif
583
+ }
584
+ # endif
585
+
586
+ if (symbolize) {
587
+ result = rb_str_intern(result);
588
+ }
589
+
491
590
  return result;
492
591
  }
493
592
 
@@ -498,12 +597,11 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
498
597
  write data;
499
598
 
500
599
  action parse_string {
501
- *result = json_string_unescape(*result, json->memo + 1, p);
600
+ *result = json_string_unescape(json->memo + 1, p, json->parsing_name || json-> freeze, json->parsing_name && json->symbolize_names);
502
601
  if (NIL_P(*result)) {
503
602
  fhold;
504
603
  fbreak;
505
604
  } else {
506
- FORCE_UTF8(*result);
507
605
  fexec p + 1;
508
606
  }
509
607
  }
@@ -530,7 +628,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
530
628
  int cs = EVIL;
531
629
  VALUE match_string;
532
630
 
533
- *result = rb_str_buf_new(0);
534
631
  %% write init;
535
632
  json->memo = p;
536
633
  %% write exec;
@@ -546,9 +643,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
546
643
  }
547
644
  }
548
645
 
549
- if (json->symbolize_names && json->parsing_name) {
550
- *result = rb_str_intern(*result);
551
- }
552
646
  if (cs >= JSON_string_first_final) {
553
647
  return p + 1;
554
648
  } else {
@@ -570,41 +664,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
570
664
 
571
665
  static VALUE convert_encoding(VALUE source)
572
666
  {
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
667
  #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);
668
+ rb_encoding *enc = rb_enc_get(source);
669
+ if (enc == rb_ascii8bit_encoding()) {
670
+ if (OBJ_FROZEN(source)) {
671
+ source = rb_str_dup(source);
607
672
  }
673
+ FORCE_UTF8(source);
674
+ } else {
675
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
676
+ }
608
677
  #endif
609
678
  return source;
610
679
  }
@@ -627,8 +696,9 @@ static VALUE convert_encoding(VALUE source)
627
696
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
628
697
  * false.
629
698
  * * *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.
699
+ * (keys) in a JSON object. Otherwise strings are returned, which is
700
+ * also the default. It's not possible to use this option in
701
+ * conjunction with the *create_additions* option.
632
702
  * * *create_additions*: If set to false, the Parser doesn't create
633
703
  * additions even if a matching class and create_id was found. This option
634
704
  * defaults to false.
@@ -679,12 +749,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
679
749
  } else {
680
750
  json->symbolize_names = 0;
681
751
  }
682
- tmp = ID2SYM(i_quirks_mode);
752
+ tmp = ID2SYM(i_freeze);
683
753
  if (option_given_p(opts, tmp)) {
684
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
685
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
754
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
686
755
  } else {
687
- json->quirks_mode = 0;
756
+ json->freeze = 0;
688
757
  }
689
758
  tmp = ID2SYM(i_create_additions);
690
759
  if (option_given_p(opts, tmp)) {
@@ -692,6 +761,11 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
692
761
  } else {
693
762
  json->create_additions = 0;
694
763
  }
764
+ if (json->symbolize_names && json->create_additions) {
765
+ rb_raise(rb_eArgError,
766
+ "options :symbolize_names and :create_additions cannot be "
767
+ " used in conjunction");
768
+ }
695
769
  tmp = ID2SYM(i_create_id);
696
770
  if (option_given_p(opts, tmp)) {
697
771
  json->create_id = rb_hash_aref(opts, tmp);
@@ -710,6 +784,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
710
784
  } else {
711
785
  json->array_class = Qnil;
712
786
  }
787
+ tmp = ID2SYM(i_decimal_class);
788
+ if (option_given_p(opts, tmp)) {
789
+ json->decimal_class = rb_hash_aref(opts, tmp);
790
+ } else {
791
+ json->decimal_class = Qnil;
792
+ }
713
793
  tmp = ID2SYM(i_match_string);
714
794
  if (option_given_p(opts, tmp)) {
715
795
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -723,16 +803,14 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
723
803
  } else {
724
804
  json->max_nesting = 100;
725
805
  json->allow_nan = 0;
726
- json->create_additions = 1;
806
+ json->create_additions = 0;
727
807
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
728
808
  json->object_class = Qnil;
729
809
  json->array_class = Qnil;
810
+ json->decimal_class = Qnil;
730
811
  }
812
+ source = convert_encoding(StringValue(source));
731
813
  StringValue(source);
732
- if (!json->quirks_mode) {
733
- source = convert_encoding(source);
734
- }
735
- json->current_nesting = 0;
736
814
  json->len = RSTRING_LEN(source);
737
815
  json->source = RSTRING_PTR(source);;
738
816
  json->Vsource = source;
@@ -746,56 +824,8 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
746
824
 
747
825
  include JSON_common;
748
826
 
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
827
  action parse_value {
798
- char *np = JSON_parse_value(json, fpc, pe, &result);
828
+ char *np = JSON_parse_value(json, fpc, pe, &result, 0);
799
829
  if (np == NULL) { fhold; fbreak; } else fexec np;
800
830
  }
801
831
 
@@ -804,26 +834,6 @@ static VALUE cParser_parse_strict(VALUE self)
804
834
  ) ignore*;
805
835
  }%%
806
836
 
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
837
  /*
828
838
  * call-seq: parse()
829
839
  *
@@ -832,12 +842,21 @@ static VALUE cParser_parse_quirks_mode(VALUE self)
832
842
  */
833
843
  static VALUE cParser_parse(VALUE self)
834
844
  {
845
+ char *p, *pe;
846
+ int cs = EVIL;
847
+ VALUE result = Qnil;
835
848
  GET_PARSER;
836
849
 
837
- if (json->quirks_mode) {
838
- return cParser_parse_quirks_mode(self);
850
+ %% write init;
851
+ p = json->source;
852
+ pe = p + json->len;
853
+ %% write exec;
854
+
855
+ if (cs >= JSON_first_final && p == pe) {
856
+ return result;
839
857
  } else {
840
- return cParser_parse_strict(self);
858
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
859
+ return Qnil;
841
860
  }
842
861
  }
843
862
 
@@ -848,6 +867,7 @@ static void JSON_mark(void *ptr)
848
867
  rb_gc_mark_maybe(json->create_id);
849
868
  rb_gc_mark_maybe(json->object_class);
850
869
  rb_gc_mark_maybe(json->array_class);
870
+ rb_gc_mark_maybe(json->decimal_class);
851
871
  rb_gc_mark_maybe(json->match_string);
852
872
  }
853
873
 
@@ -895,35 +915,34 @@ static VALUE cParser_source(VALUE self)
895
915
  return rb_str_dup(json->Vsource);
896
916
  }
897
917
 
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
918
  void Init_parser(void)
911
919
  {
920
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
921
+ rb_ext_ractor_safe(true);
922
+ #endif
923
+
924
+ #undef rb_intern
912
925
  rb_require("json/common");
913
926
  mJSON = rb_define_module("JSON");
914
927
  mExt = rb_define_module_under(mJSON, "Ext");
915
928
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
916
929
  eParserError = rb_path2class("JSON::ParserError");
917
930
  eNestingError = rb_path2class("JSON::NestingError");
931
+ rb_gc_register_mark_object(eParserError);
932
+ rb_gc_register_mark_object(eNestingError);
918
933
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
919
934
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
920
935
  rb_define_method(cParser, "parse", cParser_parse, 0);
921
936
  rb_define_method(cParser, "source", cParser_source, 0);
922
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
923
937
 
924
938
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
939
+ rb_gc_register_mark_object(CNaN);
940
+
925
941
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
942
+ rb_gc_register_mark_object(CInfinity);
943
+
926
944
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
945
+ rb_gc_register_mark_object(CMinusInfinity);
927
946
 
928
947
  i_json_creatable_p = rb_intern("json_creatable?");
929
948
  i_json_create = rb_intern("json_create");
@@ -933,9 +952,9 @@ void Init_parser(void)
933
952
  i_max_nesting = rb_intern("max_nesting");
934
953
  i_allow_nan = rb_intern("allow_nan");
935
954
  i_symbolize_names = rb_intern("symbolize_names");
936
- i_quirks_mode = rb_intern("quirks_mode");
937
955
  i_object_class = rb_intern("object_class");
938
956
  i_array_class = rb_intern("array_class");
957
+ i_decimal_class = rb_intern("decimal_class");
939
958
  i_match = rb_intern("match");
940
959
  i_match_string = rb_intern("match_string");
941
960
  i_key_p = rb_intern("key?");
@@ -943,15 +962,10 @@ void Init_parser(void)
943
962
  i_aset = rb_intern("[]=");
944
963
  i_aref = rb_intern("[]");
945
964
  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
965
+ i_new = rb_intern("new");
966
+ i_try_convert = rb_intern("try_convert");
967
+ i_freeze = rb_intern("freeze");
968
+ i_uminus = rb_intern("-@");
955
969
  }
956
970
 
957
971
  /*
data/ext/json/extconf.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  require 'mkmf'
2
- create_makefile('json')
3
2
 
3
+ create_makefile('json')
data/json.gemspec CHANGED
Binary file