oj 3.13.7 → 3.13.11

Sign up to get free protection for your applications and to get access to all the features.
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