oj 3.13.5 → 3.13.9

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: 0a287ba77407aab722c31cfa700b92a173015345bc619f4a95ef7baaeff4be93
4
- data.tar.gz: b0286ae29d7dff1f71e5691feae47761ad6203f6bdbcf457486443c29b40c6c9
3
+ metadata.gz: 646e1253e68f33e284b1efa4ec5f6c3ad9de2e52a1f4ddfbb37435ceb5e23bd0
4
+ data.tar.gz: 775d9f0169d77a6f06990cf0d1f0e1904a530567d0939471f326e7ec5ee24c37
5
5
  SHA512:
6
- metadata.gz: bd679fe51f8564ab17a24a842a7d7c31c097e6cd20b7f46c5949d19717aa24901750314426d2930752f78160bb25c157728b3ec8b1247376816b5dc2857ced27
7
- data.tar.gz: 278065333f209b2ef3d10a94dc770f78ff50d9ca2090e39b522083deb1548902f81b8f9493d689401cc4106b21cf5e6d93f17f5cc8da383f86dc1a4d0418ae43
6
+ metadata.gz: f15a8a5dabfece0fb92ebfd2be99d567890441a2774c361646fc0ab03eba1de0070106cdc0addcc6fa75cf797dcd568b2f0129954c5debbe9ffa334ea8aa7fc4
7
+ data.tar.gz: 9d3d0d399610c5209a6819df7583368c14250311249ff3f42a67c868057b96fb8f89c12657aeaf36f1ef545793038aece84f8a7524f40f77ed8636fe6d9e09f5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # CHANGELOG
2
2
 
3
+
4
+ ## 3.13.9 - 2021-10-06
5
+
6
+ - Fix mimic JSON load so that it honors the `:symbolize_names` option.
7
+
8
+ ## 3.13.8 - 2021-09-27
9
+
10
+ - Fix `Oj::Doc` behaviour for inexisting path.
11
+ ```ruby
12
+ Oj::Doc.open('{"foo":1}') do |doc|
13
+ doc.fetch('/foo/bar') # used to give `1`, now gives `nil`
14
+ doc.exists?('/foo/bar') # used to give `true`, now gives `false`
15
+ end
16
+ ```
17
+
18
+ - Fix `Oj::Parser` handling of BigDecimal. `snprint()` does not handle `%Lg` correctly but `sprintf()` does.
19
+
20
+ ## 3.13.7 - 2021-09-16
21
+
22
+ - The JSON gem allows invalid unicode so Oj, when mimicing JSON now
23
+ allows it as well. Use `:allow_invalid_unicode` to change that.
24
+
25
+ ## 3.13.6 - 2021-09-11
26
+
27
+ - Fixed unicode UTF 8 parsing in string values.
28
+
29
+ - Fixed hash key allocation issue.
30
+
31
+ - The `Oj::Parser.new()` function now allows optional arguments that
32
+ set the allowed options for the mode. As an example
33
+ `Oj::Parser.new(:usual, cache_keys: true)`.
34
+
3
35
  ## 3.13.5 - 2021-09-08
4
36
 
5
37
  - Assure value strings of zero length are not always cached.
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/fast.c CHANGED
@@ -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;
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;
@@ -516,7 +514,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
516
514
  pi.options = oj_default_options;
517
515
  pi.options.auto_define = No;
518
516
  pi.options.quirks_mode = Yes;
519
- pi.options.allow_invalid = No;
517
+ pi.options.allow_invalid = Yes;
520
518
  pi.options.empty_string = No;
521
519
  pi.options.create_ok = No;
522
520
  pi.options.allow_nan = (bang ? Yes : No);
@@ -531,11 +529,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
531
529
  if (T_HASH != rb_type(ropts)) {
532
530
  rb_raise(rb_eArgError, "options must be a hash.");
533
531
  }
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))) {
532
+ if (Qnil != (v = rb_hash_lookup(ropts, oj_symbolize_names_sym))) {
539
533
  pi.options.sym_key = (Qtrue == v) ? Yes : No;
540
534
  }
541
535
  if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
@@ -573,8 +567,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
573
567
  }
574
568
  }
575
569
  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));
570
+ pi.options.compat_bigdec = (oj_bigdecimal_class == rb_hash_lookup(ropts, oj_decimal_class_sym));
578
571
  }
579
572
  v = rb_hash_lookup(ropts, oj_max_nesting_sym);
580
573
  if (Qtrue == v) {
@@ -682,7 +675,7 @@ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
682
675
  */
683
676
  static VALUE mimic_create_id(VALUE self) {
684
677
  if (NULL != oj_default_options.create_id) {
685
- return rb_utf8_str_new(oj_default_options.create_id, oj_default_options.create_id_len);
678
+ return rb_utf8_str_new(oj_default_options.create_id, oj_default_options.create_id_len);
686
679
  }
687
680
  return rb_str_new_cstr(oj_json_class);
688
681
  }
@@ -706,7 +699,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
706
699
  No, // empty_string
707
700
  Yes, // allow_gc
708
701
  Yes, // quirks_mode
709
- No, // allow_invalid
702
+ Yes, // allow_invalid
710
703
  No, // create_ok
711
704
  No, // allow_nan
712
705
  No, // trace
@@ -853,9 +846,6 @@ void oj_mimic_json_methods(VALUE json) {
853
846
  // Pull in the JSON::State mimic file.
854
847
  state_class = rb_const_get_at(generator, rb_intern("State"));
855
848
  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
849
  }
860
850
 
861
851
  /* 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
  }
@@ -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