oj 3.13.6 → 3.13.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c01eed4e3f068cda64af85aa6fe2aa15d7c559a3d1947385a8122112ae1b80b4
4
- data.tar.gz: caba410a8bfee592344b8cfb281da48932cc2871ee3cc7fe71dadefacb55dc13
3
+ metadata.gz: e4f2c04b24ed0dc8c781036c17371378649d1aad9b927b402b2b0f3d67f9f94b
4
+ data.tar.gz: 65b50beb64e09569e7bcdcff9675a60b146de5ed78027b90de5def8eb6b57aa8
5
5
  SHA512:
6
- metadata.gz: 15dc55ed4572c0dcba2a3345aee97e5ab17f3106eef44c3d0a3c9e258915c1d95cae3bda8bbce6f21d3de08c22662a07ce7e39a52b77ff6c1f660cb576054e1f
7
- data.tar.gz: 768977fae9b1c60baa679e32eb3d66d02206eb4357c2f6c29189b1d2dd27982a59f65648f8ee11424211f4e80a2a4ca11f19b285bee18db1d08ddbaba10fa1ca
6
+ metadata.gz: 62a4e36ea67596152899cf389502a69f4f19b354dc5980c66b31ad5163b932245030bfd338ad582ec101572b56fd280c0e784b1d20567f830933627274506503
7
+ data.tar.gz: 671d6a7066b4f74c164ce4af83acbab38fcb0743c97c13985ad4f8e7f1431f67288d1bb80f74b7e55d90d6c5e727e01dc72b138b7dfda3220cbc55ae3ebf2856
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # CHANGELOG
2
2
 
3
+
4
+ ## 3.13.10 - 2021-12-12
5
+
6
+ - Fixed Oj::Doc re-entrant issue with each_child.
7
+ - Fixed each_child on empty Oj::Doc.
8
+
9
+ ## 3.13.9 - 2021-10-06
10
+
11
+ - Fix mimic JSON load so that it honors the `:symbolize_names` option.
12
+
13
+ ## 3.13.8 - 2021-09-27
14
+
15
+ - Fix `Oj::Doc` behaviour for inexisting path.
16
+ ```ruby
17
+ Oj::Doc.open('{"foo":1}') do |doc|
18
+ doc.fetch('/foo/bar') # used to give `1`, now gives `nil`
19
+ doc.exists?('/foo/bar') # used to give `true`, now gives `false`
20
+ end
21
+ ```
22
+
23
+ - Fix `Oj::Parser` handling of BigDecimal. `snprint()` does not handle `%Lg` correctly but `sprintf()` does.
24
+
25
+ ## 3.13.7 - 2021-09-16
26
+
27
+ - The JSON gem allows invalid unicode so Oj, when mimicing JSON now
28
+ allows it as well. Use `:allow_invalid_unicode` to change that.
29
+
3
30
  ## 3.13.6 - 2021-09-11
4
31
 
5
32
  - Fixed unicode UTF 8 parsing in string values.
data/README.md CHANGED
@@ -43,6 +43,15 @@ or in Bundler:
43
43
  gem 'oj'
44
44
  ```
45
45
 
46
+ ## Rails and json quickstart
47
+
48
+ See the Quickstart sections of the [Rails](pages/Rails.md) and [json](pages/JsonGem.md) docs.
49
+
50
+ ## multi_json
51
+
52
+ Code which uses [multi_json](https://github.com/intridea/multi_json)
53
+ will automatically prefer Oj if it is installed.
54
+
46
55
  ## Support
47
56
 
48
57
  [Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
data/RELEASE_NOTES.md CHANGED
@@ -5,6 +5,12 @@ see the See [{file:CHANGELOG.md}](CHANGELOG.md) file. In this file are
5
5
  the steps to take to aid in keeping things rolling after updating to
6
6
  the latest version.
7
7
 
8
+ ## 3.13.7
9
+
10
+ The default for JSON when mimicked by Oj is now to set
11
+ `:allow_invalid_unicode`. To change that behavior JSON.load, set that
12
+ option to false.
13
+
8
14
  ## 3.13.x
9
15
 
10
16
  This release included a new cache that performs better than the
data/ext/oj/custom.c CHANGED
@@ -282,7 +282,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
282
282
  Out out = (Out)ov;
283
283
  int depth = out->depth;
284
284
 
285
- if (oj_dump_ignore(out->opts, value)) {
285
+ if (dump_ignore(out->opts, value)) {
286
286
  return ST_CONTINUE;
287
287
  }
288
288
  if (out->omit_nil && Qnil == value) {
@@ -577,7 +577,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
577
577
  size_t size;
578
578
  const char *attr;
579
579
 
580
- if (oj_dump_ignore(out->opts, value)) {
580
+ if (dump_ignore(out->opts, value)) {
581
581
  return ST_CONTINUE;
582
582
  }
583
583
  if (out->omit_nil && Qnil == value) {
@@ -749,7 +749,7 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
749
749
  } else {
750
750
  fill_indent(out, d2);
751
751
  }
752
- oj_dump_custom_val(rb_ary_entry(a, i), d2, out, true);
752
+ oj_dump_custom_val(RARRAY_AREF(a, i), d2, out, true);
753
753
  if (i < cnt) {
754
754
  *out->cur++ = ',';
755
755
  }
@@ -833,7 +833,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
833
833
  v = rb_struct_aref(obj, INT2FIX(i));
834
834
  #endif
835
835
  if (ma != Qnil) {
836
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
836
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
837
837
 
838
838
  name = RSTRING_PTR(s);
839
839
  len = (int)RSTRING_LEN(s);
data/ext/oj/dump.c CHANGED
@@ -1225,17 +1225,3 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char
1225
1225
  }
1226
1226
  return cnt;
1227
1227
  }
1228
-
1229
- bool oj_dump_ignore(Options opts, VALUE obj) {
1230
- if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
1231
- VALUE *vp = opts->ignore;
1232
- VALUE clas = rb_obj_class(obj);
1233
-
1234
- for (; Qnil != *vp; vp++) {
1235
- if (clas == *vp) {
1236
- return true;
1237
- }
1238
- }
1239
- }
1240
- return false;
1241
- }
data/ext/oj/dump.h CHANGED
@@ -50,7 +50,6 @@ extern VALUE oj_remove_to_json(int argc, VALUE *argv, VALUE self);
50
50
 
51
51
  extern int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format);
52
52
 
53
- extern bool oj_dump_ignore(Options opts, VALUE obj);
54
53
  extern time_t oj_sec_from_time_hard_way(VALUE obj);
55
54
 
56
55
  inline static void assure_size(Out out, size_t len) {
@@ -69,6 +68,20 @@ inline static void fill_indent(Out out, int cnt) {
69
68
  }
70
69
  }
71
70
 
71
+ inline static bool dump_ignore(Options opts, VALUE obj) {
72
+ if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
73
+ VALUE *vp = opts->ignore;
74
+ VALUE clas = rb_obj_class(obj);
75
+
76
+ for (; Qnil != *vp; vp++) {
77
+ if (clas == *vp) {
78
+ return true;
79
+ }
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+
72
85
  inline static void dump_ulong(unsigned long num, Out out) {
73
86
  char buf[32];
74
87
  char *b = buf + sizeof(buf) - 1;
data/ext/oj/dump_compat.c CHANGED
@@ -182,7 +182,7 @@ dump_array(VALUE a, int depth, Out out, bool as_ok) {
182
182
  } else {
183
183
  fill_indent(out, d2);
184
184
  }
185
- oj_dump_compat_val(rb_ary_entry(a, i), d2, out, true);
185
+ oj_dump_compat_val(RARRAY_AREF(a, i), d2, out, true);
186
186
  if (i < cnt) {
187
187
  *out->cur++ = ',';
188
188
  }
data/ext/oj/dump_object.c CHANGED
@@ -157,7 +157,7 @@ static void dump_array_class(VALUE a, VALUE clas, int depth, Out out) {
157
157
  } else {
158
158
  fill_indent(out, d2);
159
159
  }
160
- oj_dump_obj_val(rb_ary_entry(a, i), d2, out);
160
+ oj_dump_obj_val(RARRAY_AREF(a, i), d2, out);
161
161
  if (i < cnt) {
162
162
  *out->cur++ = ',';
163
163
  }
@@ -218,7 +218,7 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
218
218
  int depth = out->depth;
219
219
  long size = depth * out->indent + 1;
220
220
 
221
- if (oj_dump_ignore(out->opts, value)) {
221
+ if (dump_ignore(out->opts, value)) {
222
222
  return ST_CONTINUE;
223
223
  }
224
224
  if (out->omit_nil && Qnil == value) {
@@ -226,47 +226,54 @@ static int hash_cb(VALUE key, VALUE value, VALUE ov) {
226
226
  }
227
227
  assure_size(out, size);
228
228
  fill_indent(out, depth);
229
- if (rb_type(key) == T_STRING) {
229
+ switch (rb_type(key)) {
230
+ case T_STRING:
230
231
  dump_str_class(key, Qundef, depth, out);
231
232
  *out->cur++ = ':';
232
233
  oj_dump_obj_val(value, depth, out);
233
- } else if (rb_type(key) == T_SYMBOL) {
234
+ break;
235
+
236
+ case T_SYMBOL:
234
237
  dump_sym(key, 0, out, false);
235
238
  *out->cur++ = ':';
236
239
  oj_dump_obj_val(value, depth, out);
237
- } else {
238
- int d2 = depth + 1;
239
- long s2 = size + out->indent + 1;
240
- int i;
241
- int started = 0;
242
- uint8_t b;
240
+ break;
243
241
 
244
- assure_size(out, s2 + 15);
245
- *out->cur++ = '"';
246
- *out->cur++ = '^';
247
- *out->cur++ = '#';
248
- out->hash_cnt++;
249
- for (i = 28; 0 <= i; i -= 4) {
250
- b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
251
- if ('\0' != b) {
252
- started = 1;
253
- }
254
- if (started) {
255
- *out->cur++ = hex_chars[b];
242
+ default:
243
+ {
244
+ int d2 = depth + 1;
245
+ long s2 = size + out->indent + 1;
246
+ int i;
247
+ int started = 0;
248
+ uint8_t b;
249
+
250
+ assure_size(out, s2 + 15);
251
+ *out->cur++ = '"';
252
+ *out->cur++ = '^';
253
+ *out->cur++ = '#';
254
+ out->hash_cnt++;
255
+ for (i = 28; 0 <= i; i -= 4) {
256
+ b = (uint8_t)((out->hash_cnt >> i) & 0x0000000F);
257
+ if ('\0' != b) {
258
+ started = 1;
259
+ }
260
+ if (started) {
261
+ *out->cur++ = hex_chars[b];
262
+ }
256
263
  }
264
+ *out->cur++ = '"';
265
+ *out->cur++ = ':';
266
+ *out->cur++ = '[';
267
+ fill_indent(out, d2);
268
+ oj_dump_obj_val(key, d2, out);
269
+ assure_size(out, s2);
270
+ *out->cur++ = ',';
271
+ fill_indent(out, d2);
272
+ oj_dump_obj_val(value, d2, out);
273
+ assure_size(out, size);
274
+ fill_indent(out, depth);
275
+ *out->cur++ = ']';
257
276
  }
258
- *out->cur++ = '"';
259
- *out->cur++ = ':';
260
- *out->cur++ = '[';
261
- fill_indent(out, d2);
262
- oj_dump_obj_val(key, d2, out);
263
- assure_size(out, s2);
264
- *out->cur++ = ',';
265
- fill_indent(out, d2);
266
- oj_dump_obj_val(value, d2, out);
267
- assure_size(out, size);
268
- fill_indent(out, depth);
269
- *out->cur++ = ']';
270
277
  }
271
278
  out->depth = depth;
272
279
  *out->cur++ = ',';
@@ -342,7 +349,7 @@ static int dump_attr_cb(ID key, VALUE value, VALUE ov) {
342
349
  size_t size = depth * out->indent + 1;
343
350
  const char *attr = rb_id2name(key);
344
351
 
345
- if (oj_dump_ignore(out->opts, value)) {
352
+ if (dump_ignore(out->opts, value)) {
346
353
  return ST_CONTINUE;
347
354
  }
348
355
  if (out->omit_nil && Qnil == value) {
@@ -605,7 +612,7 @@ static void dump_obj_attrs(VALUE obj, VALUE clas, slot_t id, int depth, Out out)
605
612
  }
606
613
  value = rb_ivar_get(obj, vid);
607
614
 
608
- if (oj_dump_ignore(out->opts, value)) {
615
+ if (dump_ignore(out->opts, value)) {
609
616
  continue;
610
617
  }
611
618
  if (out->omit_nil && Qnil == value) {
@@ -694,7 +701,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
694
701
 
695
702
  *out->cur++ = '[';
696
703
  for (i = 0; i < cnt; i++) {
697
- volatile VALUE s = rb_sym2str(rb_ary_entry(ma, i));
704
+ volatile VALUE s = rb_sym2str(RARRAY_AREF(ma, i));
698
705
 
699
706
  name = RSTRING_PTR(s);
700
707
  len = (int)RSTRING_LEN(s);
@@ -730,7 +737,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
730
737
 
731
738
  for (i = 0; i < cnt; i++) {
732
739
  v = RSTRUCT_GET(obj, i);
733
- if (oj_dump_ignore(out->opts, v)) {
740
+ if (dump_ignore(out->opts, v)) {
734
741
  v = Qnil;
735
742
  }
736
743
  assure_size(out, size);
@@ -748,7 +755,7 @@ static void dump_struct(VALUE obj, int depth, Out out, bool as_ok) {
748
755
  for (i = 0; i < slen; i++) {
749
756
  assure_size(out, size);
750
757
  fill_indent(out, d3);
751
- if (oj_dump_ignore(out->opts, v)) {
758
+ if (dump_ignore(out->opts, v)) {
752
759
  v = Qnil;
753
760
  }
754
761
  oj_dump_obj_val(rb_struct_aref(obj, INT2FIX(i)), d3, out, 0, 0, true);
data/ext/oj/dump_strict.c CHANGED
@@ -153,9 +153,9 @@ static void dump_array(VALUE a, int depth, Out out, bool as_ok) {
153
153
  fill_indent(out, d2);
154
154
  }
155
155
  if (NullMode == out->opts->mode) {
156
- oj_dump_null_val(rb_ary_entry(a, i), d2, out);
156
+ oj_dump_null_val(RARRAY_AREF(a, i), d2, out);
157
157
  } else {
158
- oj_dump_strict_val(rb_ary_entry(a, i), d2, out);
158
+ oj_dump_strict_val(RARRAY_AREF(a, i), d2, out);
159
159
  }
160
160
  if (i < cnt) {
161
161
  *out->cur++ = ',';
data/ext/oj/fast.c CHANGED
@@ -771,7 +771,7 @@ static VALUE parse_json(VALUE clas, char *json, bool given, bool allocated) {
771
771
  pi.doc = doc;
772
772
  #if IS_WINDOWS
773
773
  // assume a 1M stack and give half to ruby
774
- pi.stack_min = (void*)((char*)&pi - (512 * 1024));
774
+ pi.stack_min = (void *)((char *)&pi - (512 * 1024));
775
775
  #else
776
776
  {
777
777
  struct rlimit lim;
@@ -879,6 +879,10 @@ static Leaf get_leaf(Leaf *stack, Leaf *lp, const char *path) {
879
879
  }
880
880
  } else if (NULL == leaf->elements) {
881
881
  leaf = NULL;
882
+ } else if (STR_VAL == leaf->value_type || RUBY_VAL == leaf->value_type) {
883
+ // We are trying to get a children of a leaf, which
884
+ // doesn't exist.
885
+ leaf = NULL;
882
886
  } else if (COL_VAL == leaf->value_type) {
883
887
  Leaf first = leaf->elements->next;
884
888
  Leaf e = first;
@@ -1373,8 +1377,8 @@ static VALUE doc_fetch(int argc, VALUE *argv, VALUE self) {
1373
1377
  * Returns true if the value at the location identified by the path exists.
1374
1378
  * @param [String] path path to the location
1375
1379
  * @example
1376
- * Oj::Doc.open('[1,2]') { |doc| doc.exists('/1') } #=> true
1377
- * Oj::Doc.open('[1,2]') { |doc| doc.exists('/3') } #=> false
1380
+ * Oj::Doc.open('[1,2]') { |doc| doc.exists?('/1') } #=> true
1381
+ * Oj::Doc.open('[1,2]') { |doc| doc.exists?('/3') } #=> false
1378
1382
  */
1379
1383
  static VALUE doc_exists(VALUE self, VALUE str) {
1380
1384
  Doc doc;
@@ -1488,6 +1492,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1488
1492
  Doc doc = self_doc(self);
1489
1493
  const char *path = 0;
1490
1494
  size_t wlen;
1495
+ Leaf * where_orig = doc->where;
1491
1496
 
1492
1497
  wlen = doc->where - doc->where_path;
1493
1498
  if (0 < wlen) {
@@ -1504,9 +1509,13 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1504
1509
  if (0 < wlen) {
1505
1510
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1506
1511
  }
1512
+ doc->where = where_orig;
1507
1513
  return Qnil;
1508
1514
  }
1509
1515
  }
1516
+ if (NULL == doc->where || NULL == *doc->where) {
1517
+ return Qnil;
1518
+ }
1510
1519
  if (COL_VAL == (*doc->where)->value_type && 0 != (*doc->where)->elements) {
1511
1520
  Leaf first = (*doc->where)->elements->next;
1512
1521
  Leaf e = first;
@@ -1521,6 +1530,7 @@ static VALUE doc_each_child(int argc, VALUE *argv, VALUE self) {
1521
1530
  if (0 < wlen) {
1522
1531
  memcpy(doc->where_path, save_path, sizeof(Leaf) * (wlen + 1));
1523
1532
  }
1533
+ doc->where = where_orig;
1524
1534
  }
1525
1535
  return Qnil;
1526
1536
  }
data/ext/oj/intern.c CHANGED
@@ -186,6 +186,7 @@ static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int a
186
186
  char * end = class_name + sizeof(class_name) - 1;
187
187
  char * s;
188
188
  const char *n = name;
189
+ size_t nlen = len;
189
190
 
190
191
  clas = rb_cObject;
191
192
  for (s = class_name; 0 < len; n++, len--) {
@@ -208,7 +209,12 @@ static VALUE resolve_classpath(ParseInfo pi, const char *name, size_t len, int a
208
209
  }
209
210
  *s = '\0';
210
211
  if (Qundef == (clas = resolve_classname(clas, class_name, auto_define))) {
211
- oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class %s is not defined", name);
212
+ if (sizeof(class_name) <= nlen) {
213
+ nlen = sizeof(class_name) - 1;
214
+ }
215
+ strncpy(class_name, name, nlen);
216
+ class_name[nlen] = '\0';
217
+ oj_set_error_at(pi, error_class, __FILE__, __LINE__, "class '%s' is not defined", class_name);
212
218
  if (Qnil != error_class) {
213
219
  pi->err_class = error_class;
214
220
  }
data/ext/oj/mimic_json.c CHANGED
@@ -6,8 +6,6 @@
6
6
  #include "oj.h"
7
7
  #include "parse.h"
8
8
 
9
- static VALUE symbolize_names_sym = Qundef;
10
-
11
9
  extern const char oj_json_class[];
12
10
 
13
11
  VALUE oj_array_nl_sym;
@@ -274,7 +272,7 @@ static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
274
272
  size_t i;
275
273
 
276
274
  for (i = 0; i < cnt; i++) {
277
- mimic_walk(Qnil, rb_ary_entry(obj, i), proc);
275
+ mimic_walk(Qnil, RARRAY_AREF(obj, i), proc);
278
276
  }
279
277
  break;
280
278
  }
@@ -501,6 +499,52 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
501
499
  return mimic_generate_core(2, rargs, &copts);
502
500
  }
503
501
 
502
+ static int parse_options_cb(VALUE k, VALUE v, VALUE info) {
503
+ struct _parseInfo *pi = (struct _parseInfo *)info;
504
+
505
+ if (oj_symbolize_names_sym == k) {
506
+ pi->options.sym_key = (Qtrue == v) ? Yes : No;
507
+ } else if (oj_quirks_mode_sym == k) {
508
+ pi->options.quirks_mode = (Qtrue == v) ? Yes : No;
509
+ } else if (oj_create_additions_sym == k) {
510
+ pi->options.create_ok = (Qtrue == v) ? Yes : No;
511
+ } else if (oj_allow_nan_sym == k) {
512
+ pi->options.allow_nan = (Qtrue == v) ? Yes : No;
513
+ } else if (oj_hash_class_sym == k) {
514
+ if (Qnil == v) {
515
+ pi->options.hash_class = Qnil;
516
+ } else {
517
+ rb_check_type(v, T_CLASS);
518
+ pi->options.hash_class = v;
519
+ }
520
+ } else if (oj_object_class_sym == k) {
521
+ if (Qnil == v) {
522
+ pi->options.hash_class = Qnil;
523
+ } else {
524
+ rb_check_type(v, T_CLASS);
525
+ pi->options.hash_class = v;
526
+ }
527
+ } else if (oj_array_class_sym == k) {
528
+ if (Qnil == v) {
529
+ pi->options.array_class = Qnil;
530
+ } else {
531
+ rb_check_type(v, T_CLASS);
532
+ pi->options.array_class = v;
533
+ }
534
+ } else if (oj_decimal_class_sym == k) {
535
+ pi->options.compat_bigdec = (oj_bigdecimal_class == v);
536
+ } else if (oj_max_nesting_sym == k) {
537
+ if (Qtrue == v) {
538
+ pi->max_depth = 100;
539
+ } else if (Qfalse == v || Qnil == v) {
540
+ pi->max_depth = 0;
541
+ } else if (T_FIXNUM == rb_type(v)) {
542
+ pi->max_depth = NUM2INT(v);
543
+ }
544
+ }
545
+ return ST_CONTINUE;
546
+ }
547
+
504
548
  static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
505
549
  struct _parseInfo pi;
506
550
  VALUE ropts;
@@ -516,7 +560,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
516
560
  pi.options = oj_default_options;
517
561
  pi.options.auto_define = No;
518
562
  pi.options.quirks_mode = Yes;
519
- pi.options.allow_invalid = No;
563
+ pi.options.allow_invalid = Yes;
520
564
  pi.options.empty_string = No;
521
565
  pi.options.create_ok = No;
522
566
  pi.options.allow_nan = (bang ? Yes : No);
@@ -526,64 +570,11 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
526
570
  pi.max_depth = 100;
527
571
 
528
572
  if (Qnil != ropts) {
529
- VALUE v;
530
-
531
573
  if (T_HASH != rb_type(ropts)) {
532
574
  rb_raise(rb_eArgError, "options must be a hash.");
533
575
  }
534
- if (Qundef == symbolize_names_sym) {
535
- symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
536
- rb_gc_register_address(&symbolize_names_sym);
537
- }
538
- if (Qnil != (v = rb_hash_lookup(ropts, symbolize_names_sym))) {
539
- pi.options.sym_key = (Qtrue == v) ? Yes : No;
540
- }
541
- if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
542
- pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
543
- }
544
- if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
545
- pi.options.create_ok = (Qtrue == v) ? Yes : No;
546
- }
547
- if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
548
- pi.options.allow_nan = (Qtrue == v) ? Yes : No;
549
- }
550
576
 
551
- if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
552
- if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
553
- pi.options.hash_class = Qnil;
554
- } else {
555
- rb_check_type(v, T_CLASS);
556
- pi.options.hash_class = v;
557
- }
558
- }
559
- if (oj_hash_has_key(ropts, oj_object_class_sym)) {
560
- if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
561
- pi.options.hash_class = Qnil;
562
- } else {
563
- rb_check_type(v, T_CLASS);
564
- pi.options.hash_class = v;
565
- }
566
- }
567
- if (oj_hash_has_key(ropts, oj_array_class_sym)) {
568
- if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
569
- pi.options.array_class = Qnil;
570
- } else {
571
- rb_check_type(v, T_CLASS);
572
- pi.options.array_class = v;
573
- }
574
- }
575
- if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
576
- pi.options.compat_bigdec = (oj_bigdecimal_class ==
577
- rb_hash_lookup(ropts, oj_decimal_class_sym));
578
- }
579
- v = rb_hash_lookup(ropts, oj_max_nesting_sym);
580
- if (Qtrue == v) {
581
- pi.max_depth = 100;
582
- } else if (Qfalse == v || Qnil == v) {
583
- pi.max_depth = 0;
584
- } else if (T_FIXNUM == rb_type(v)) {
585
- pi.max_depth = NUM2INT(v);
586
- }
577
+ rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
587
578
  oj_parse_opt_match_string(&pi.options.str_rx, ropts);
588
579
  if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
589
580
  rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
@@ -682,7 +673,7 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
682
673
  */
683
674
  static VALUE mimic_create_id(VALUE self) {
684
675
  if (NULL != oj_default_options.create_id) {
685
- return rb_utf8_str_new(oj_default_options.create_id, oj_default_options.create_id_len);
676
+ return rb_utf8_str_new(oj_default_options.create_id, oj_default_options.create_id_len);
686
677
  }
687
678
  return rb_str_new_cstr(oj_json_class);
688
679
  }
@@ -706,7 +697,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
706
697
  No, // empty_string
707
698
  Yes, // allow_gc
708
699
  Yes, // quirks_mode
709
- No, // allow_invalid
700
+ Yes, // allow_invalid
710
701
  No, // create_ok
711
702
  No, // allow_nan
712
703
  No, // trace
@@ -853,9 +844,6 @@ void oj_mimic_json_methods(VALUE json) {
853
844
  // Pull in the JSON::State mimic file.
854
845
  state_class = rb_const_get_at(generator, rb_intern("State"));
855
846
  rb_gc_register_mark_object(state_class);
856
-
857
- symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
858
- rb_gc_register_address(&symbolize_names_sym);
859
847
  }
860
848
 
861
849
  /* Document-module: JSON