oj 3.13.7 → 3.13.11

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.
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;
@@ -526,63 +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 == rb_hash_lookup(ropts, oj_decimal_class_sym));
577
- }
578
- v = rb_hash_lookup(ropts, oj_max_nesting_sym);
579
- if (Qtrue == v) {
580
- pi.max_depth = 100;
581
- } else if (Qfalse == v || Qnil == v) {
582
- pi.max_depth = 0;
583
- } else if (T_FIXNUM == rb_type(v)) {
584
- pi.max_depth = NUM2INT(v);
585
- }
577
+ rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
586
578
  oj_parse_opt_match_string(&pi.options.str_rx, ropts);
587
579
  if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
588
580
  rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
@@ -852,9 +844,6 @@ void oj_mimic_json_methods(VALUE json) {
852
844
  // Pull in the JSON::State mimic file.
853
845
  state_class = rb_const_get_at(generator, rb_intern("State"));
854
846
  rb_gc_register_mark_object(state_class);
855
-
856
- symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
857
- rb_gc_register_address(&symbolize_names_sym);
858
847
  }
859
848
 
860
849
  /* Document-module: JSON
data/ext/oj/object.c CHANGED
@@ -35,7 +35,7 @@ static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
35
35
  return ID2SYM(rb_intern3(kval->key + 1, kval->klen - 1, oj_utf8_encoding));
36
36
  }
37
37
  if (Yes == pi->options.sym_key) {
38
- return ID2SYM(rb_intern3(kval->key, kval->klen, oj_utf8_encoding));
38
+ return ID2SYM(rb_intern3(kval->key, kval->klen, oj_utf8_encoding));
39
39
  }
40
40
  #if HAVE_RB_ENC_INTERNED_STR
41
41
  rkey = rb_enc_interned_str(kval->key, kval->klen, oj_utf8_encoding);
@@ -60,21 +60,16 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
60
60
  }
61
61
  rstr = oj_circ_array_get(pi->circ_array, i);
62
62
  } else {
63
- rstr = rb_utf8_str_new(str, len);
63
+ rstr = rb_utf8_str_new(str, len);
64
64
  }
65
65
  return rstr;
66
66
  }
67
67
 
68
- #if (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
69
- static VALUE oj_parse_xml_time(const char *str, int len) {
70
- return rb_funcall(rb_cTime, oj_parse_id, 1, rb_str_new(str, len));
71
- }
72
- #else
73
68
  // The much faster approach (4x faster)
74
69
  static int parse_num(const char *str, const char *end, int cnt) {
75
- int n = 0;
70
+ int n = 0;
76
71
  char c;
77
- int i;
72
+ int i;
78
73
 
79
74
  for (i = cnt; 0 < i; i--, str++) {
80
75
  c = *str;
@@ -88,9 +83,9 @@ static int parse_num(const char *str, const char *end, int cnt) {
88
83
 
89
84
  VALUE
90
85
  oj_parse_xml_time(const char *str, int len) {
91
- VALUE args[8];
86
+ VALUE args[8];
92
87
  const char *end = str + len;
93
- int n;
88
+ int n;
94
89
 
95
90
  // year
96
91
  if (0 > (n = parse_num(str, end, 4))) {
@@ -201,7 +196,6 @@ oj_parse_xml_time(const char *str, int len) {
201
196
  }
202
197
  return rb_funcall2(rb_cTime, oj_new_id, 7, args);
203
198
  }
204
- #endif
205
199
 
206
200
  static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
207
201
  const char *key = kval->key;
@@ -226,13 +220,10 @@ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t
226
220
  }
227
221
  parent->val = odd->clas;
228
222
  parent->odd_args = oj_odd_alloc_args(odd);
229
- } break;
230
- case 'm':
231
- parent->val = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding));
232
- break;
233
- case 's':
234
- parent->val = rb_utf8_str_new(str, len);
235
223
  break;
224
+ }
225
+ case 'm': parent->val = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding)); break;
226
+ case 's': parent->val = rb_utf8_str_new(str, len); break;
236
227
  case 'c': // class
237
228
  {
238
229
  VALUE clas = oj_name2class(pi, str, len, Yes == pi->options.auto_define, rb_eArgError);
@@ -242,7 +233,8 @@ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t
242
233
  } else {
243
234
  parent->val = clas;
244
235
  }
245
- } break;
236
+ break;
237
+ }
246
238
  case 't': // time
247
239
  parent->val = oj_parse_xml_time(str, (int)len);
248
240
  break;
@@ -282,22 +274,21 @@ static int hat_num(ParseInfo pi, Val parent, Val kval, NumInfo ni) {
282
274
  VALUE args[8];
283
275
 
284
276
  sec_as_time(t, &ti);
285
- args[0] = LONG2NUM((long)(ti.year));
286
- args[1] = LONG2NUM(ti.mon);
287
- args[2] = LONG2NUM(ti.day);
288
- args[3] = LONG2NUM(ti.hour);
289
- args[4] = LONG2NUM(ti.min);
290
- args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
291
- args[6] = LONG2NUM(ni->exp);
277
+ args[0] = LONG2NUM((long)(ti.year));
278
+ args[1] = LONG2NUM(ti.mon);
279
+ args[2] = LONG2NUM(ti.day);
280
+ args[3] = LONG2NUM(ti.hour);
281
+ args[4] = LONG2NUM(ti.min);
282
+ args[5] = rb_float_new((double)ti.sec + ((double)nsec + 0.5) / 1000000000.0);
283
+ args[6] = LONG2NUM(ni->exp);
292
284
  parent->val = rb_funcall2(rb_cTime, oj_new_id, 7, args);
293
285
  } else {
294
286
  parent->val = rb_time_nano_new(ni->i, (long)nsec);
295
287
  }
296
288
  }
297
289
  break;
298
- case 'i': // circular index
299
- if (!ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp &&
300
- 0 != pi->circ_array) { // fixnum
290
+ case 'i': // circular index
291
+ if (!ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp && 0 != pi->circ_array) { // fixnum
301
292
  if (Qnil == parent->val) {
302
293
  parent->val = rb_hash_new();
303
294
  }
@@ -334,7 +325,7 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
334
325
  int i, cnt = (int)RARRAY_LEN(e1);
335
326
 
336
327
  for (i = 0; i < cnt; i++) {
337
- rstr = rb_ary_entry(e1, i);
328
+ rstr = RARRAY_AREF(e1, i);
338
329
  args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
339
330
  }
340
331
  sc = rb_funcall2(rb_cStruct, oj_new_id, cnt, args);
@@ -402,9 +393,7 @@ WHICH_TYPE:
402
393
  }
403
394
  break;
404
395
  case T_HASH:
405
- rb_hash_aset(parent->val,
406
- calc_hash_key(pi, kval, parent->k1),
407
- str_to_value(pi, str, len, orig));
396
+ rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), str_to_value(pi, str, len, orig));
408
397
  break;
409
398
  case T_STRING:
410
399
  rval = str_to_value(pi, str, len, orig);
@@ -481,8 +470,8 @@ WHICH_TYPE:
481
470
  rb_hash_aset(parent->val, calc_hash_key(pi, kval, parent->k1), rval);
482
471
  break;
483
472
  case T_OBJECT:
484
- if (2 == klen && '^' == *key && 'i' == key[1] && !ni->infinity && !ni->neg &&
485
- 1 == ni->div && 0 == ni->exp && 0 != pi->circ_array) { // fixnum
473
+ if (2 == klen && '^' == *key && 'i' == key[1] && !ni->infinity && !ni->neg && 1 == ni->div && 0 == ni->exp &&
474
+ 0 != pi->circ_array) { // fixnum
486
475
  oj_circ_array_set(pi->circ_array, parent->val, ni->i);
487
476
  } else {
488
477
  rval = oj_num_as_value(ni);
@@ -559,11 +548,7 @@ WHICH_TYPE:
559
548
  volatile VALUE *a = RARRAY_PTR(value);
560
549
 
561
550
  if (2 != len) {
562
- oj_set_error_at(pi,
563
- oj_parse_error_class,
564
- __FILE__,
565
- __LINE__,
566
- "invalid hash pair");
551
+ oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid hash pair");
567
552
  return;
568
553
  }
569
554
  rb_hash_aset(parent->val, *a, a[1]);
@@ -637,10 +622,7 @@ static void end_hash(ParseInfo pi) {
637
622
  } else if (NULL != parent->odd_args) {
638
623
  OddArgs oa = parent->odd_args;
639
624
 
640
- parent->val = rb_funcall2(oa->odd->create_obj,
641
- oa->odd->create_op,
642
- oa->odd->attr_cnt,
643
- oa->args);
625
+ parent->val = rb_funcall2(oa->odd->create_obj, oa->odd->create_op, oa->odd->attr_cnt, oa->args);
644
626
  oj_odd_free(oa);
645
627
  parent->odd_args = NULL;
646
628
  }
@@ -653,8 +635,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
653
635
  volatile VALUE rval = Qnil;
654
636
 
655
637
  // orig lets us know whether the string was ^r1 or \u005er1
656
- if (3 <= len && 0 != pi->circ_array && '^' == orig[0] &&
657
- 0 == rb_array_len(stack_peek(&pi->stack)->val)) {
638
+ if (3 <= len && 0 != pi->circ_array && '^' == orig[0] && 0 == rb_array_len(stack_peek(&pi->stack)->val)) {
658
639
  if ('i' == str[1]) {
659
640
  long i = read_long(str + 2, len - 2);
660
641