oj 3.16.11 → 3.17.6

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/object.c CHANGED
@@ -31,7 +31,7 @@ inline static long read_long(const char *str, size_t len) {
31
31
  static VALUE calc_hash_key(ParseInfo pi, Val kval, char k1) {
32
32
  volatile VALUE rkey;
33
33
 
34
- if (':' == k1) {
34
+ if (':' == k1 && 0 < kval->klen) {
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) {
@@ -54,7 +54,7 @@ static VALUE str_to_value(ParseInfo pi, const char *str, size_t len, const char
54
54
  } else if (pi->circ_array && 3 <= len && '^' == *orig && 'r' == orig[1]) {
55
55
  long i = read_long(str + 2, len - 2);
56
56
 
57
- if (0 > i) {
57
+ if (0 >= i) {
58
58
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a valid ID number");
59
59
  return Qnil;
60
60
  }
@@ -207,7 +207,7 @@ oj_parse_xml_time(const char *str, int len) {
207
207
 
208
208
  static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t len) {
209
209
  const char *key = kval->key;
210
- int klen = kval->klen;
210
+ size_t klen = kval->klen;
211
211
 
212
212
  if (2 == klen) {
213
213
  switch (key[1]) {
@@ -230,7 +230,12 @@ static int hat_cstr(ParseInfo pi, Val parent, Val kval, const char *str, size_t
230
230
  parent->odd_args = oj_odd_alloc_args(odd);
231
231
  break;
232
232
  }
233
- case 'm': parent->val = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding)); break;
233
+ case 'm':
234
+ if (0 == len) {
235
+ return 0;
236
+ }
237
+ parent->val = ID2SYM(rb_intern3(str + 1, len - 1, oj_utf8_encoding));
238
+ break;
234
239
  case 's': parent->val = rb_utf8_str_new(str, len); break;
235
240
  case 'c': // class
236
241
  {
@@ -319,20 +324,26 @@ static int hat_value(ParseInfo pi, Val parent, const char *key, size_t klen, vol
319
324
  e1 = *RARRAY_CONST_PTR(value);
320
325
  // check for anonymous Struct
321
326
  if (T_ARRAY == rb_type(e1)) {
322
- VALUE args[1024];
323
- volatile VALUE rstr;
327
+ // Build the member-name list in a GC-managed Ruby array. Using a
328
+ // fixed C buffer (VALUE args[1024]) here overflowed the stack when
329
+ // the JSON supplied more than 1024 member names.
330
+ volatile VALUE names = rb_ary_new2(RARRAY_LEN(e1));
324
331
  size_t i;
325
332
  size_t cnt = RARRAY_LEN(e1);
326
333
 
327
334
  for (i = 0; i < cnt; i++) {
328
- rstr = RARRAY_AREF(e1, i);
329
- args[i] = rb_funcall(rstr, oj_to_sym_id, 0);
335
+ rb_ary_push(names, rb_funcall(RARRAY_AREF(e1, i), oj_to_sym_id, 0));
330
336
  }
331
- sc = rb_funcall2(rb_cStruct, oj_new_id, (int)cnt, args);
337
+ sc = rb_apply(rb_cStruct, oj_new_id, names);
332
338
  } else {
333
339
  // If struct is not defined then we let this fail and raise an exception.
334
340
  sc = oj_name2struct(pi, *RARRAY_CONST_PTR(value), rb_eArgError);
335
341
  }
342
+ if (Qundef == sc || Qnil == sc) {
343
+ // oj_name2struct already recorded the error; do not pass an
344
+ // unresolved (Qundef) class on to rb_obj_alloc/rb_class_new_instance.
345
+ return 1;
346
+ }
336
347
  if (sc == rb_cRange) {
337
348
  parent->val = rb_class_new_instance((int)(len - 1), RARRAY_CONST_PTR(value) + 1, rb_cRange);
338
349
  } else {
@@ -389,7 +400,7 @@ void oj_set_obj_ivar(Val parent, Val kval, VALUE value) {
389
400
 
390
401
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
391
402
  const char *key = kval->key;
392
- int klen = kval->klen;
403
+ size_t klen = kval->klen;
393
404
  Val parent = stack_peek(&pi->stack);
394
405
  volatile VALUE rval = Qnil;
395
406
 
@@ -431,7 +442,7 @@ WHICH_TYPE:
431
442
  if (0 != oj_odd_set_arg(parent->odd_args, kval->key, kval->klen, rval)) {
432
443
  char buf[256];
433
444
 
434
- if ((int)sizeof(buf) - 1 <= klen) {
445
+ if (sizeof(buf) - 1 <= klen) {
435
446
  klen = sizeof(buf) - 2;
436
447
  }
437
448
  memcpy(buf, key, klen);
@@ -460,7 +471,7 @@ WHICH_TYPE:
460
471
 
461
472
  static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
462
473
  const char *key = kval->key;
463
- int klen = kval->klen;
474
+ size_t klen = kval->klen;
464
475
  Val parent = stack_peek(&pi->stack);
465
476
  volatile VALUE rval = Qnil;
466
477
 
@@ -500,7 +511,7 @@ WHICH_TYPE:
500
511
  if (0 != oj_odd_set_arg(parent->odd_args, key, klen, rval)) {
501
512
  char buf[256];
502
513
 
503
- if ((int)sizeof(buf) - 1 <= klen) {
514
+ if (sizeof(buf) - 1 <= klen) {
504
515
  klen = sizeof(buf) - 2;
505
516
  }
506
517
  memcpy(buf, key, klen);
@@ -529,7 +540,7 @@ WHICH_TYPE:
529
540
 
530
541
  static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
531
542
  const char *key = kval->key;
532
- int klen = kval->klen;
543
+ size_t klen = kval->klen;
533
544
  Val parent = stack_peek(&pi->stack);
534
545
 
535
546
  WHICH_TYPE:
@@ -585,7 +596,7 @@ WHICH_TYPE:
585
596
  } else if (0 != oj_odd_set_arg(parent->odd_args, key, klen, value)) {
586
597
  char buf[256];
587
598
 
588
- if ((int)sizeof(buf) - 1 <= klen) {
599
+ if (sizeof(buf) - 1 <= klen) {
589
600
  klen = sizeof(buf) - 2;
590
601
  }
591
602
  memcpy(buf, key, klen);
data/ext/oj/odd.c CHANGED
@@ -166,7 +166,11 @@ Odd oj_get_oddc(const char *classname, size_t len) {
166
166
  if (len == odd->clen && 0 == strncmp(classname, odd->classname, len)) {
167
167
  return odd;
168
168
  }
169
- if (odd->is_module && 0 == strncmp(odd->classname, classname, odd->clen) && ':' == classname[odd->clen]) {
169
+ // The module test needs a "::" after the module name, so the name has
170
+ // to be shorter than what it is compared against. Without that the
171
+ // comparison and the character after it both run past len.
172
+ if (odd->is_module && odd->clen < len && 0 == strncmp(odd->classname, classname, odd->clen) &&
173
+ ':' == classname[odd->clen]) {
170
174
  return odd;
171
175
  }
172
176
  }
@@ -195,7 +199,7 @@ int oj_odd_set_arg(OddArgs args, const char *key, size_t klen, VALUE value) {
195
199
  int i;
196
200
 
197
201
  for (i = args->odd->attr_cnt, np = args->odd->attr_names, vp = args->args; 0 < i; i--, np++, vp++) {
198
- if (0 == strncmp(key, *np, klen) && '\0' == *((*np) + klen)) {
202
+ if (klen == strlen(*np) && 0 == memcmp(key, *np, klen)) {
199
203
  *vp = value;
200
204
  return 0;
201
205
  }