json 1.8.2 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.travis.yml +11 -9
  4. data/{CHANGES → CHANGES.md} +220 -89
  5. data/Gemfile +10 -6
  6. data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
  7. data/{README.rdoc → README.md} +204 -137
  8. data/Rakefile +35 -113
  9. data/VERSION +1 -1
  10. data/ext/json/ext/fbuffer/fbuffer.h +0 -3
  11. data/ext/json/ext/generator/generator.c +215 -110
  12. data/ext/json/ext/generator/generator.h +18 -5
  13. data/ext/json/ext/parser/extconf.rb +3 -0
  14. data/ext/json/ext/parser/parser.c +422 -508
  15. data/ext/json/ext/parser/parser.h +15 -8
  16. data/ext/json/ext/parser/parser.rl +151 -200
  17. data/ext/json/extconf.rb +0 -1
  18. data/java/src/json/ext/ByteListTranscoder.java +1 -2
  19. data/java/src/json/ext/Generator.java +44 -22
  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 +3 -56
  23. data/java/src/json/ext/OptionsReader.java +2 -3
  24. data/java/src/json/ext/Parser.java +132 -415
  25. data/java/src/json/ext/Parser.rl +48 -124
  26. data/java/src/json/ext/ParserService.java +1 -2
  27. data/java/src/json/ext/RuntimeInfo.java +1 -6
  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 -2
  32. data/json.gemspec +0 -0
  33. data/json_pure.gemspec +22 -29
  34. data/lib/json.rb +379 -29
  35. data/lib/json/add/bigdecimal.rb +3 -2
  36. data/lib/json/add/complex.rb +4 -3
  37. data/lib/json/add/core.rb +1 -0
  38. data/lib/json/add/date.rb +1 -1
  39. data/lib/json/add/date_time.rb +1 -1
  40. data/lib/json/add/exception.rb +1 -1
  41. data/lib/json/add/ostruct.rb +3 -3
  42. data/lib/json/add/range.rb +1 -1
  43. data/lib/json/add/rational.rb +3 -2
  44. data/lib/json/add/regexp.rb +3 -3
  45. data/lib/json/add/set.rb +29 -0
  46. data/lib/json/add/struct.rb +1 -1
  47. data/lib/json/add/symbol.rb +1 -1
  48. data/lib/json/add/time.rb +1 -1
  49. data/lib/json/common.rb +335 -128
  50. data/lib/json/ext.rb +0 -6
  51. data/lib/json/generic_object.rb +5 -4
  52. data/lib/json/pure.rb +2 -8
  53. data/lib/json/pure/generator.rb +64 -127
  54. data/lib/json/pure/parser.rb +42 -82
  55. data/lib/json/version.rb +2 -1
  56. data/references/rfc7159.txt +899 -0
  57. data/tests/fixtures/obsolete_fail1.json +1 -0
  58. data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
  59. data/tests/json_common_interface_test.rb +126 -0
  60. data/tests/json_encoding_test.rb +107 -0
  61. data/tests/json_ext_parser_test.rb +15 -0
  62. data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +10 -8
  63. data/tests/{test_json_generate.rb → json_generator_test.rb} +123 -39
  64. data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
  65. data/tests/json_parser_test.rb +472 -0
  66. data/tests/json_string_matching_test.rb +38 -0
  67. data/tests/{setup_variant.rb → test_helper.rb} +6 -0
  68. data/tools/diff.sh +18 -0
  69. data/tools/fuzz.rb +1 -9
  70. metadata +46 -53
  71. data/COPYING +0 -58
  72. data/COPYING-json-jruby +0 -57
  73. data/GPL +0 -340
  74. data/TODO +0 -1
  75. data/data/example.json +0 -1
  76. data/data/index.html +0 -38
  77. data/data/prototype.js +0 -4184
  78. data/tests/fixtures/fail1.json +0 -1
  79. data/tests/test_json.rb +0 -553
  80. data/tests/test_json_encoding.rb +0 -65
  81. data/tests/test_json_string_matching.rb +0 -39
  82. 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,26 +57,34 @@ 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);
69
68
  static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self);
70
69
  static VALUE cParser_parse(VALUE self);
71
- static JSON_Parser *JSON_allocate(void);
72
70
  static void JSON_mark(void *json);
73
71
  static void JSON_free(void *json);
74
72
  static VALUE cJSON_parser_s_allocate(VALUE klass);
75
73
  static VALUE cParser_source(VALUE self);
76
- #ifdef TypedData_Wrap_Struct
74
+ #ifndef ZALLOC
75
+ #define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
76
+ static inline void *ruby_zalloc(size_t n)
77
+ {
78
+ void *p = ruby_xmalloc(n);
79
+ memset(p, 0, n);
80
+ return p;
81
+ }
82
+ #endif
83
+ #ifdef TypedData_Make_Struct
77
84
  static const rb_data_type_t JSON_Parser_type;
78
85
  #define NEW_TYPEDDATA_WRAPPER 1
79
86
  #else
80
- #define TypedData_Wrap_Struct(klass, ignore, json) Data_Wrap_Struct(klass, JSON_mark, JSON_free, json)
87
+ #define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json)
81
88
  #define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json)
82
89
  #endif
83
90
 
@@ -1,9 +1,31 @@
1
1
  #include "../fbuffer/fbuffer.h"
2
2
  #include "parser.h"
3
3
 
4
+ #if defined HAVE_RUBY_ENCODING_H
5
+ # define EXC_ENCODING rb_utf8_encoding(),
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
- static const char digit_values[256] = {
28
+ static const signed char digit_values[256] = {
7
29
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
8
30
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9
31
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
@@ -22,20 +44,20 @@ static const char digit_values[256] = {
22
44
 
23
45
  static UTF32 unescape_unicode(const unsigned char *p)
24
46
  {
25
- char b;
47
+ signed char b;
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
 
@@ -65,21 +87,15 @@ static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
65
87
  return len;
66
88
  }
67
89
 
68
- #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;
72
- #else
73
- static ID i_iconv;
74
- #endif
75
-
76
90
  static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
77
91
  static VALUE CNaN, CInfinity, CMinusInfinity;
92
+ static VALUE cBigDecimal = Qundef;
78
93
 
79
94
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
80
- i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
81
- i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
82
- 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;
83
99
 
84
100
  %%{
85
101
  machine JSON_common;
@@ -117,11 +133,12 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
117
133
 
118
134
  action parse_value {
119
135
  VALUE v = Qnil;
120
- char *np = JSON_parse_value(json, fpc, pe, &v);
136
+ char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
121
137
  if (np == NULL) {
122
138
  fhold; fbreak;
123
139
  } else {
124
140
  if (NIL_P(json->object_class)) {
141
+ OBJ_FREEZE(last_name);
125
142
  rb_hash_aset(*result, last_name, v);
126
143
  } else {
127
144
  rb_funcall(*result, i_aset, 2, last_name, v);
@@ -150,14 +167,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
150
167
  ) @exit;
151
168
  }%%
152
169
 
153
- static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
170
+ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
154
171
  {
155
172
  int cs = EVIL;
156
173
  VALUE last_name = Qnil;
157
174
  VALUE object_class = json->object_class;
158
175
 
159
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
160
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
176
+ if (json->max_nesting && current_nesting > json->max_nesting) {
177
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
161
178
  }
162
179
 
163
180
  *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
@@ -206,14 +223,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
206
223
  if (json->allow_nan) {
207
224
  *result = CNaN;
208
225
  } else {
209
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
226
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
210
227
  }
211
228
  }
212
229
  action parse_infinity {
213
230
  if (json->allow_nan) {
214
231
  *result = CInfinity;
215
232
  } else {
216
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
233
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
217
234
  }
218
235
  }
219
236
  action parse_string {
@@ -223,13 +240,13 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
223
240
 
224
241
  action parse_number {
225
242
  char *np;
226
- if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
243
+ if(pe > fpc + 8 && !strncmp(MinusInfinity, fpc, 9)) {
227
244
  if (json->allow_nan) {
228
245
  *result = CMinusInfinity;
229
246
  fexec p + 10;
230
247
  fhold; fbreak;
231
248
  } else {
232
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
249
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
233
250
  }
234
251
  }
235
252
  np = JSON_parse_float(json, fpc, pe, result);
@@ -241,23 +258,19 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
241
258
 
242
259
  action parse_array {
243
260
  char *np;
244
- json->current_nesting++;
245
- np = JSON_parse_array(json, fpc, pe, result);
246
- json->current_nesting--;
261
+ np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
247
262
  if (np == NULL) { fhold; fbreak; } else fexec np;
248
263
  }
249
264
 
250
265
  action parse_object {
251
266
  char *np;
252
- json->current_nesting++;
253
- np = JSON_parse_object(json, fpc, pe, result);
254
- json->current_nesting--;
267
+ np = JSON_parse_object(json, fpc, pe, result, current_nesting + 1);
255
268
  if (np == NULL) { fhold; fbreak; } else fexec np;
256
269
  }
257
270
 
258
271
  action exit { fhold; fbreak; }
259
272
 
260
- main := (
273
+ main := ignore* (
261
274
  Vnull @parse_null |
262
275
  Vfalse @parse_false |
263
276
  Vtrue @parse_true |
@@ -267,10 +280,10 @@ main := (
267
280
  begin_string >parse_string |
268
281
  begin_array >parse_array |
269
282
  begin_object >parse_object
270
- ) %*exit;
283
+ ) ignore* %*exit;
271
284
  }%%
272
285
 
273
- static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
286
+ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
274
287
  {
275
288
  int cs = EVIL;
276
289
 
@@ -328,6 +341,19 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
328
341
  ) (^[0-9Ee.\-]? @exit );
329
342
  }%%
330
343
 
344
+ static int is_bigdecimal_class(VALUE obj)
345
+ {
346
+ if (cBigDecimal == Qundef) {
347
+ if (rb_const_defined(rb_cObject, i_BigDecimal)) {
348
+ cBigDecimal = rb_const_get_at(rb_cObject, i_BigDecimal);
349
+ }
350
+ else {
351
+ return 0;
352
+ }
353
+ }
354
+ return obj == cBigDecimal;
355
+ }
356
+
331
357
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
332
358
  {
333
359
  int cs = EVIL;
@@ -341,7 +367,17 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
341
367
  fbuffer_clear(json->fbuffer);
342
368
  fbuffer_append(json->fbuffer, json->memo, len);
343
369
  fbuffer_append_char(json->fbuffer, '\0');
344
- *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
370
+ if (NIL_P(json->decimal_class)) {
371
+ *result = rb_float_new(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
372
+ } else {
373
+ VALUE text;
374
+ text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
375
+ if (is_bigdecimal_class(json->decimal_class)) {
376
+ *result = rb_funcall(Qnil, i_BigDecimal, 1, text);
377
+ } else {
378
+ *result = rb_funcall(json->decimal_class, i_new, 1, text);
379
+ }
380
+ }
345
381
  return p + 1;
346
382
  } else {
347
383
  return NULL;
@@ -357,7 +393,7 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
357
393
 
358
394
  action parse_value {
359
395
  VALUE v = Qnil;
360
- char *np = JSON_parse_value(json, fpc, pe, &v);
396
+ char *np = JSON_parse_value(json, fpc, pe, &v, current_nesting);
361
397
  if (np == NULL) {
362
398
  fhold; fbreak;
363
399
  } else {
@@ -380,13 +416,13 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
380
416
  end_array @exit;
381
417
  }%%
382
418
 
383
- static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
419
+ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
384
420
  {
385
421
  int cs = EVIL;
386
422
  VALUE array_class = json->array_class;
387
423
 
388
- if (json->max_nesting && json->current_nesting > json->max_nesting) {
389
- rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
424
+ if (json->max_nesting && current_nesting > json->max_nesting) {
425
+ rb_raise(eNestingError, "nesting of %d is too deep", current_nesting);
390
426
  }
391
427
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
392
428
 
@@ -396,7 +432,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
396
432
  if(cs >= JSON_array_first_final) {
397
433
  return p + 1;
398
434
  } else {
399
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
435
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
400
436
  return NULL;
401
437
  }
402
438
  }
@@ -436,13 +472,21 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
436
472
  break;
437
473
  case 'u':
438
474
  if (pe > stringEnd - 4) {
439
- return Qnil;
475
+ rb_enc_raise(
476
+ EXC_ENCODING eParserError,
477
+ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
478
+ );
440
479
  } else {
441
480
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
442
481
  pe += 3;
443
482
  if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
444
483
  pe++;
445
- if (pe > stringEnd - 6) return Qnil;
484
+ if (pe > stringEnd - 6) {
485
+ rb_enc_raise(
486
+ EXC_ENCODING eParserError,
487
+ "%u: incomplete surrogate pair at '%s'", __LINE__, p
488
+ );
489
+ }
446
490
  if (pe[0] == '\\' && pe[1] == 'u') {
447
491
  UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
448
492
  ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
@@ -528,6 +572,8 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
528
572
 
529
573
  if (json->symbolize_names && json->parsing_name) {
530
574
  *result = rb_str_intern(*result);
575
+ } else if (RB_TYPE_P(*result, T_STRING)) {
576
+ rb_str_resize(*result, RSTRING_LEN(*result));
531
577
  }
532
578
  if (cs >= JSON_string_first_final) {
533
579
  return p + 1;
@@ -550,41 +596,16 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
550
596
 
551
597
  static VALUE convert_encoding(VALUE source)
552
598
  {
553
- char *ptr = RSTRING_PTR(source);
554
- long len = RSTRING_LEN(source);
555
- if (len < 2) {
556
- rb_raise(eParserError, "A JSON text must at least contain two octets!");
557
- }
558
599
  #ifdef HAVE_RUBY_ENCODING_H
559
- {
560
- VALUE encoding = rb_funcall(source, i_encoding, 0);
561
- if (encoding == CEncoding_ASCII_8BIT) {
562
- 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);
564
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
565
- source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
566
- } 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);
568
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
569
- source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
570
- } else {
571
- source = rb_str_dup(source);
572
- FORCE_UTF8(source);
573
- }
574
- } else {
575
- source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
576
- }
577
- }
578
- #else
579
- if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
580
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
581
- } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
582
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
583
- } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
584
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
585
- } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
586
- source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
600
+ rb_encoding *enc = rb_enc_get(source);
601
+ if (enc == rb_ascii8bit_encoding()) {
602
+ if (OBJ_FROZEN(source)) {
603
+ source = rb_str_dup(source);
587
604
  }
605
+ FORCE_UTF8(source);
606
+ } else {
607
+ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding());
608
+ }
588
609
  #endif
589
610
  return source;
590
611
  }
@@ -607,8 +628,9 @@ static VALUE convert_encoding(VALUE source)
607
628
  * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
608
629
  * false.
609
630
  * * *symbolize_names*: If set to true, returns symbols for the names
610
- * (keys) in a JSON object. Otherwise strings are returned, which is also
611
- * the default.
631
+ * (keys) in a JSON object. Otherwise strings are returned, which is
632
+ * also the default. It's not possible to use this option in
633
+ * conjunction with the *create_additions* option.
612
634
  * * *create_additions*: If set to false, the Parser doesn't create
613
635
  * additions even if a matching class and create_id was found. This option
614
636
  * defaults to false.
@@ -623,12 +645,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
623
645
  if (json->Vsource) {
624
646
  rb_raise(rb_eTypeError, "already initialized instance");
625
647
  }
648
+ #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
649
+ rb_scan_args(argc, argv, "1:", &source, &opts);
650
+ #else
626
651
  rb_scan_args(argc, argv, "11", &source, &opts);
652
+ #endif
627
653
  if (!NIL_P(opts)) {
654
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
628
655
  opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
629
656
  if (NIL_P(opts)) {
630
657
  rb_raise(rb_eArgError, "opts needs to be like a hash");
631
658
  } else {
659
+ #endif
632
660
  VALUE tmp = ID2SYM(i_max_nesting);
633
661
  if (option_given_p(opts, tmp)) {
634
662
  VALUE max_nesting = rb_hash_aref(opts, tmp);
@@ -653,19 +681,17 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
653
681
  } else {
654
682
  json->symbolize_names = 0;
655
683
  }
656
- tmp = ID2SYM(i_quirks_mode);
657
- if (option_given_p(opts, tmp)) {
658
- VALUE quirks_mode = rb_hash_aref(opts, tmp);
659
- json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
660
- } else {
661
- json->quirks_mode = 0;
662
- }
663
684
  tmp = ID2SYM(i_create_additions);
664
685
  if (option_given_p(opts, tmp)) {
665
686
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
666
687
  } else {
667
688
  json->create_additions = 0;
668
689
  }
690
+ if (json->symbolize_names && json->create_additions) {
691
+ rb_raise(rb_eArgError,
692
+ "options :symbolize_names and :create_additions cannot be "
693
+ " used in conjunction");
694
+ }
669
695
  tmp = ID2SYM(i_create_id);
670
696
  if (option_given_p(opts, tmp)) {
671
697
  json->create_id = rb_hash_aref(opts, tmp);
@@ -684,6 +710,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
684
710
  } else {
685
711
  json->array_class = Qnil;
686
712
  }
713
+ tmp = ID2SYM(i_decimal_class);
714
+ if (option_given_p(opts, tmp)) {
715
+ json->decimal_class = rb_hash_aref(opts, tmp);
716
+ } else {
717
+ json->decimal_class = Qnil;
718
+ }
687
719
  tmp = ID2SYM(i_match_string);
688
720
  if (option_given_p(opts, tmp)) {
689
721
  VALUE match_string = rb_hash_aref(opts, tmp);
@@ -691,20 +723,19 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
691
723
  } else {
692
724
  json->match_string = Qnil;
693
725
  }
726
+ #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
694
727
  }
728
+ #endif
695
729
  } else {
696
730
  json->max_nesting = 100;
697
731
  json->allow_nan = 0;
698
- json->create_additions = 1;
732
+ json->create_additions = 0;
699
733
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
700
734
  json->object_class = Qnil;
701
735
  json->array_class = Qnil;
736
+ json->decimal_class = Qnil;
702
737
  }
703
- source = rb_convert_type(source, T_STRING, "String", "to_str");
704
- if (!json->quirks_mode) {
705
- source = convert_encoding(StringValue(source));
706
- }
707
- json->current_nesting = 0;
738
+ source = convert_encoding(StringValue(source));
708
739
  StringValue(source);
709
740
  json->len = RSTRING_LEN(source);
710
741
  json->source = RSTRING_PTR(source);;
@@ -719,56 +750,8 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
719
750
 
720
751
  include JSON_common;
721
752
 
722
- action parse_object {
723
- char *np;
724
- json->current_nesting = 1;
725
- np = JSON_parse_object(json, fpc, pe, &result);
726
- if (np == NULL) { fhold; fbreak; } else fexec np;
727
- }
728
-
729
- action parse_array {
730
- char *np;
731
- json->current_nesting = 1;
732
- np = JSON_parse_array(json, fpc, pe, &result);
733
- if (np == NULL) { fhold; fbreak; } else fexec np;
734
- }
735
-
736
- main := ignore* (
737
- begin_object >parse_object |
738
- begin_array >parse_array
739
- ) ignore*;
740
- }%%
741
-
742
- static VALUE cParser_parse_strict(VALUE self)
743
- {
744
- char *p, *pe;
745
- int cs = EVIL;
746
- VALUE result = Qnil;
747
- GET_PARSER;
748
-
749
- %% write init;
750
- p = json->source;
751
- pe = p + json->len;
752
- %% write exec;
753
-
754
- if (cs >= JSON_first_final && p == pe) {
755
- return result;
756
- } else {
757
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
758
- return Qnil;
759
- }
760
- }
761
-
762
-
763
- %%{
764
- machine JSON_quirks_mode;
765
-
766
- write data;
767
-
768
- include JSON_common;
769
-
770
753
  action parse_value {
771
- char *np = JSON_parse_value(json, fpc, pe, &result);
754
+ char *np = JSON_parse_value(json, fpc, pe, &result, 0);
772
755
  if (np == NULL) { fhold; fbreak; } else fexec np;
773
756
  }
774
757
 
@@ -777,26 +760,6 @@ static VALUE cParser_parse_strict(VALUE self)
777
760
  ) ignore*;
778
761
  }%%
779
762
 
780
- static VALUE cParser_parse_quirks_mode(VALUE self)
781
- {
782
- char *p, *pe;
783
- int cs = EVIL;
784
- VALUE result = Qnil;
785
- GET_PARSER;
786
-
787
- %% write init;
788
- p = json->source;
789
- pe = p + json->len;
790
- %% write exec;
791
-
792
- if (cs >= JSON_quirks_mode_first_final && p == pe) {
793
- return result;
794
- } else {
795
- rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
796
- return Qnil;
797
- }
798
- }
799
-
800
763
  /*
801
764
  * call-seq: parse()
802
765
  *
@@ -805,24 +768,24 @@ static VALUE cParser_parse_quirks_mode(VALUE self)
805
768
  */
806
769
  static VALUE cParser_parse(VALUE self)
807
770
  {
771
+ char *p, *pe;
772
+ int cs = EVIL;
773
+ VALUE result = Qnil;
808
774
  GET_PARSER;
809
775
 
810
- if (json->quirks_mode) {
811
- return cParser_parse_quirks_mode(self);
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;
812
783
  } else {
813
- return cParser_parse_strict(self);
784
+ rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
785
+ return Qnil;
814
786
  }
815
787
  }
816
788
 
817
-
818
- static JSON_Parser *JSON_allocate(void)
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
789
  static void JSON_mark(void *ptr)
827
790
  {
828
791
  JSON_Parser *json = ptr;
@@ -830,6 +793,7 @@ static void JSON_mark(void *ptr)
830
793
  rb_gc_mark_maybe(json->create_id);
831
794
  rb_gc_mark_maybe(json->object_class);
832
795
  rb_gc_mark_maybe(json->array_class);
796
+ rb_gc_mark_maybe(json->decimal_class);
833
797
  rb_gc_mark_maybe(json->match_string);
834
798
  }
835
799
 
@@ -859,8 +823,10 @@ static const rb_data_type_t JSON_Parser_type = {
859
823
 
860
824
  static VALUE cJSON_parser_s_allocate(VALUE klass)
861
825
  {
862
- JSON_Parser *json = JSON_allocate();
863
- return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json);
826
+ JSON_Parser *json;
827
+ VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
828
+ json->fbuffer = fbuffer_alloc(0);
829
+ return obj;
864
830
  }
865
831
 
866
832
  /*
@@ -875,35 +841,30 @@ static VALUE cParser_source(VALUE self)
875
841
  return rb_str_dup(json->Vsource);
876
842
  }
877
843
 
878
- /*
879
- * call-seq: quirks_mode?()
880
- *
881
- * Returns a true, if this parser is in quirks_mode, false otherwise.
882
- */
883
- static VALUE cParser_quirks_mode_p(VALUE self)
884
- {
885
- GET_PARSER;
886
- return json->quirks_mode ? Qtrue : Qfalse;
887
- }
888
-
889
-
890
- void Init_parser()
844
+ void Init_parser(void)
891
845
  {
846
+ #undef rb_intern
892
847
  rb_require("json/common");
893
848
  mJSON = rb_define_module("JSON");
894
849
  mExt = rb_define_module_under(mJSON, "Ext");
895
850
  cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
896
851
  eParserError = rb_path2class("JSON::ParserError");
897
852
  eNestingError = rb_path2class("JSON::NestingError");
853
+ rb_gc_register_mark_object(eParserError);
854
+ rb_gc_register_mark_object(eNestingError);
898
855
  rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
899
856
  rb_define_method(cParser, "initialize", cParser_initialize, -1);
900
857
  rb_define_method(cParser, "parse", cParser_parse, 0);
901
858
  rb_define_method(cParser, "source", cParser_source, 0);
902
- rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
903
859
 
904
860
  CNaN = rb_const_get(mJSON, rb_intern("NaN"));
861
+ rb_gc_register_mark_object(CNaN);
862
+
905
863
  CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
864
+ rb_gc_register_mark_object(CInfinity);
865
+
906
866
  CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
867
+ rb_gc_register_mark_object(CMinusInfinity);
907
868
 
908
869
  i_json_creatable_p = rb_intern("json_creatable?");
909
870
  i_json_create = rb_intern("json_create");
@@ -913,9 +874,9 @@ void Init_parser()
913
874
  i_max_nesting = rb_intern("max_nesting");
914
875
  i_allow_nan = rb_intern("allow_nan");
915
876
  i_symbolize_names = rb_intern("symbolize_names");
916
- i_quirks_mode = rb_intern("quirks_mode");
917
877
  i_object_class = rb_intern("object_class");
918
878
  i_array_class = rb_intern("array_class");
879
+ i_decimal_class = rb_intern("decimal_class");
919
880
  i_match = rb_intern("match");
920
881
  i_match_string = rb_intern("match_string");
921
882
  i_key_p = rb_intern("key?");
@@ -923,18 +884,8 @@ void Init_parser()
923
884
  i_aset = rb_intern("[]=");
924
885
  i_aref = rb_intern("[]");
925
886
  i_leftshift = rb_intern("<<");
926
- #ifdef HAVE_RUBY_ENCODING_H
927
- CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
928
- CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
929
- CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
930
- CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
931
- CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
932
- CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
933
- i_encoding = rb_intern("encoding");
934
- i_encode = rb_intern("encode");
935
- #else
936
- i_iconv = rb_intern("iconv");
937
- #endif
887
+ i_new = rb_intern("new");
888
+ i_BigDecimal = rb_intern("BigDecimal");
938
889
  }
939
890
 
940
891
  /*