oj 3.15.0 → 3.15.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 929e5766d8a556ed9590574901fe8268979fd6c165d10e1a2a8601a594dd6897
4
- data.tar.gz: 966fedee6a16f73c004b56050474377ae48521f5858da962f0f0416b5636a4c3
3
+ metadata.gz: 257582096951b3c4db4b4979c49afd542ae855ba454bd6d51dcb1a69f68c2405
4
+ data.tar.gz: d835a958d019f7034e93d3f97ca1829fad74a4e26743f6a8b2b581c03ac9f14a
5
5
  SHA512:
6
- metadata.gz: f458f616c33c48d84cb0e1d2c1c45e8b677609c19251345328721fe3b7b6c4c5aa1fd4906da2234b60889a6e3bb45ee0371e7de7565bb6d1aa7d924e231e36dd
7
- data.tar.gz: fbbf233fc1ce57739d2fe538c179a24282e4c043740c2b47cce29745e3847712afa7828d321b877a3c29ab7d2216e7185af9a85bb9c8eb96b6036f9e3e49c1d1
6
+ metadata.gz: 374e55547de2db4b2199c05bebe5fa74953021883f7f609e328466c076016817b0cb8a7be03ead9c68b3fe4895eb5de0bcd60e1384ff7f1a5f7cd480824faba0
7
+ data.tar.gz: ec9cf41116602a51c49ff73ba6fc39ecbb501d51cbab0a6065bb38d2ac15a7f42332dc66f0d97df40bea6da5fafbc15209d06039180829c4c4b299b0e138676e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 3.15.1 - 2023-07-30
4
+
5
+ - Add protection against some using `require 'oj/json`, an internal file.
6
+
7
+ - Fixed non-json errors when in compat mode.
8
+
3
9
  ## 3.15.0 - 2023-06-02
4
10
 
5
11
  - Added `omit_null_byte` option when dumping.
data/ext/oj/code.c CHANGED
@@ -185,24 +185,17 @@ void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
185
185
  } else {
186
186
  char buf[32];
187
187
  char *b = buf + sizeof(buf) - 1;
188
- int neg = 0;
188
+ bool neg = false;
189
189
  long num = attrs->num;
190
190
  size_t cnt = 0;
191
191
 
192
192
  if (0 > num) {
193
- neg = 1;
193
+ neg = true;
194
194
  num = -num;
195
195
  }
196
196
  *b-- = '\0';
197
197
  if (0 < num) {
198
- for (; 0 < num; num /= 10, b--) {
199
- *b = (num % 10) + '0';
200
- }
201
- if (neg) {
202
- *b = '-';
203
- } else {
204
- b++;
205
- }
198
+ b = oj_longlong_to_string(num, neg, b);
206
199
  } else {
207
200
  *b = '0';
208
201
  }
data/ext/oj/compat.c CHANGED
@@ -13,32 +13,19 @@
13
13
  #include "trace.h"
14
14
 
15
15
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
16
- const char *key = kval->key;
17
- int klen = kval->klen;
18
- Val parent = stack_peek(&pi->stack);
19
- volatile VALUE rkey = kval->key_val;
16
+ const char *key = kval->key;
17
+ int klen = kval->klen;
18
+ Val parent = stack_peek(&pi->stack);
20
19
 
21
- if (Qundef == rkey && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
20
+ if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
22
21
  *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
23
22
  0 == strncmp(pi->options.create_id, key, klen)) {
24
23
  parent->classname = oj_strndup(str, len);
25
24
  parent->clen = len;
26
25
  } else {
27
26
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
27
+ volatile VALUE rkey = oj_calc_hash_key(pi, kval);
28
28
 
29
- if (Qundef == rkey) {
30
- if (Yes != pi->options.cache_keys) {
31
- if (Yes == pi->options.sym_key) {
32
- rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
33
- } else {
34
- rkey = rb_utf8_str_new(key, klen);
35
- }
36
- } else if (Yes == pi->options.sym_key) {
37
- rkey = oj_sym_intern(key, klen);
38
- } else {
39
- rkey = oj_str_intern(key, klen);
40
- }
41
- }
42
29
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
43
30
  VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
44
31
 
data/ext/oj/custom.c CHANGED
@@ -889,12 +889,11 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
889
889
  ///// load functions /////
890
890
 
891
891
  static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
892
- const char *key = kval->key;
893
- int klen = kval->klen;
894
- Val parent = stack_peek(&pi->stack);
895
- volatile VALUE rkey = kval->key_val;
892
+ const char *key = kval->key;
893
+ int klen = kval->klen;
894
+ Val parent = stack_peek(&pi->stack);
896
895
 
897
- if (Qundef == rkey && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
896
+ if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
898
897
  *pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
899
898
  0 == strncmp(pi->options.create_id, key, klen)) {
900
899
  parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
@@ -907,15 +906,8 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
907
906
  }
908
907
  } else {
909
908
  volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
910
- // volatile VALUE rstr = rb_utf8_str_new(str, len);
909
+ volatile VALUE rkey = oj_calc_hash_key(pi, kval);
911
910
 
912
- if (Qundef == rkey) {
913
- if (Yes == pi->options.sym_key) {
914
- rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
915
- } else {
916
- rkey = rb_utf8_str_new(key, klen);
917
- }
918
- }
919
911
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
920
912
  VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
921
913
 
data/ext/oj/dump.c CHANGED
@@ -1010,11 +1010,33 @@ static const char digits_table[] = "\
1010
1010
  80818283848586878889\
1011
1011
  90919293949596979899";
1012
1012
 
1013
+ char *oj_longlong_to_string(long long num, bool negative, char *buf) {
1014
+ while (100 <= num) {
1015
+ unsigned idx = num % 100 * 2;
1016
+ *buf-- = digits_table[idx + 1];
1017
+ *buf-- = digits_table[idx];
1018
+ num /= 100;
1019
+ }
1020
+ if (num < 10) {
1021
+ *buf-- = num + '0';
1022
+ } else {
1023
+ *buf-- = digits_table[num * 2 + 1];
1024
+ *buf-- = digits_table[num * 2];
1025
+ }
1026
+
1027
+ if (negative) {
1028
+ *buf = '-';
1029
+ } else {
1030
+ buf++;
1031
+ }
1032
+ return buf;
1033
+ }
1034
+
1013
1035
  void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1014
1036
  char buf[32];
1015
1037
  char *b = buf + sizeof(buf) - 1;
1016
1038
  long long num = NUM2LL(obj);
1017
- int neg = 0;
1039
+ bool neg = false;
1018
1040
  size_t cnt = 0;
1019
1041
  bool dump_as_string = false;
1020
1042
 
@@ -1023,7 +1045,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1023
1045
  dump_as_string = true;
1024
1046
  }
1025
1047
  if (0 > num) {
1026
- neg = 1;
1048
+ neg = true;
1027
1049
  num = -num;
1028
1050
  }
1029
1051
  *b-- = '\0';
@@ -1032,24 +1054,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1032
1054
  *b-- = '"';
1033
1055
  }
1034
1056
  if (0 < num) {
1035
- while (100 <= num) {
1036
- unsigned idx = num % 100 * 2;
1037
- *b-- = digits_table[idx + 1];
1038
- *b-- = digits_table[idx];
1039
- num /= 100;
1040
- }
1041
- if (num < 10) {
1042
- *b-- = num + '0';
1043
- } else {
1044
- *b-- = digits_table[num * 2 + 1];
1045
- *b-- = digits_table[num * 2];
1046
- }
1047
-
1048
- if (neg) {
1049
- *b = '-';
1050
- } else {
1051
- b++;
1052
- }
1057
+ b = oj_longlong_to_string(num, neg, b);
1053
1058
  } else {
1054
1059
  *b = '0';
1055
1060
  }
data/ext/oj/dump.h CHANGED
@@ -93,10 +93,7 @@ inline static void dump_ulong(unsigned long num, Out out) {
93
93
 
94
94
  *b-- = '\0';
95
95
  if (0 < num) {
96
- for (; 0 < num; num /= 10, b--) {
97
- *b = (num % 10) + '0';
98
- }
99
- b++;
96
+ b = oj_longlong_to_string((long long)num, false, b);
100
97
  } else {
101
98
  *b = '0';
102
99
  }
data/ext/oj/extconf.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mkmf'
2
4
  require 'rbconfig'
3
5
 
@@ -6,7 +8,7 @@ dir_config(extension_name)
6
8
 
7
9
  parts = RUBY_DESCRIPTION.split(' ')
8
10
  type = parts[0]
9
- type = type[4..-1] if type.start_with?('tcs-')
11
+ type = type[4..] if type.start_with?('tcs-')
10
12
  is_windows = RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
11
13
  platform = RUBY_PLATFORM
12
14
  version = RUBY_VERSION.split('.')
@@ -56,7 +58,7 @@ dflags.each do |k, v|
56
58
  end
57
59
 
58
60
  $CPPFLAGS += ' -Wall'
59
- #puts "*** $CPPFLAGS: #{$CPPFLAGS}"
61
+ # puts "*** $CPPFLAGS: #{$CPPFLAGS}"
60
62
  # Adding the __attribute__ flag only works with gcc compilers and even then it
61
63
  # does not work to check args with varargs so just remove the check.
62
64
  CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
data/ext/oj/fast.c CHANGED
@@ -40,7 +40,7 @@ typedef struct _doc {
40
40
  Leaf *where; // points to current location
41
41
  Leaf where_path[MAX_STACK]; // points to head of path
42
42
  char *json;
43
- unsigned long size; // number of leaves/branches in the doc
43
+ unsigned long size; // number of leaves/branches in the doc
44
44
  VALUE self;
45
45
  Batch batches;
46
46
  struct _batch batch0;
@@ -114,10 +114,7 @@ inline static char *ulong_fill(char *s, size_t num) {
114
114
  char *b = buf + sizeof(buf) - 1;
115
115
 
116
116
  *b-- = '\0';
117
- for (; 0 < num; num /= 10, b--) {
118
- *b = (num % 10) + '0';
119
- }
120
- b++;
117
+ b = oj_longlong_to_string((long long)num, false, b);
121
118
  if ('\0' == *b) {
122
119
  b--;
123
120
  *b = '0';
@@ -576,7 +573,7 @@ static char *read_quoted_value(ParseInfo pi) {
576
573
  char *h = pi->s; // head
577
574
  char *t = h; // tail
578
575
 
579
- h++; // skip quote character
576
+ h++; // skip quote character
580
577
  t++;
581
578
  value = h;
582
579
  for (; '"' != *h; h++, t++) {
data/ext/oj/mimic_json.c CHANGED
@@ -574,7 +574,6 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
574
574
  if (T_HASH != rb_type(ropts)) {
575
575
  rb_raise(rb_eArgError, "options must be a hash.");
576
576
  }
577
-
578
577
  rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
579
578
  v = rb_hash_lookup(ropts, oj_max_nesting_sym);
580
579
  if (Qtrue == v) {
data/ext/oj/oj.c CHANGED
@@ -232,7 +232,7 @@ struct _options oj_default_options = {
232
232
  NULL, // tail
233
233
  {'\0'}, // err
234
234
  },
235
- NULL, // ignore
235
+ NULL, // ignore
236
236
  };
237
237
 
238
238
  /* Document-method: default_options()
@@ -1294,9 +1294,9 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1294
1294
 
1295
1295
  oj_out_init(arg.out);
1296
1296
 
1297
- arg.out->omit_nil = copts.dump_opts.omit_nil;
1297
+ arg.out->omit_nil = copts.dump_opts.omit_nil;
1298
1298
  arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
1299
- arg.out->caller = CALLER_DUMP;
1299
+ arg.out->caller = CALLER_DUMP;
1300
1300
 
1301
1301
  return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
1302
1302
  }
@@ -1343,7 +1343,7 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1343
1343
 
1344
1344
  oj_out_init(&out);
1345
1345
 
1346
- out.omit_nil = copts.dump_opts.omit_nil;
1346
+ out.omit_nil = copts.dump_opts.omit_nil;
1347
1347
  out.omit_null_byte = copts.dump_opts.omit_null_byte;
1348
1348
  // For obj.to_json or generate nan is not allowed but if called from dump
1349
1349
  // it is.
data/ext/oj/oj.h CHANGED
@@ -262,12 +262,13 @@ extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
262
262
  extern bool oj_hash_has_key(VALUE hash, VALUE key);
263
263
  extern void oj_parse_options(VALUE ropts, Options copts);
264
264
 
265
- extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
266
- extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
267
- extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
268
- extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
269
- extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
270
- extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
265
+ extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
266
+ extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
267
+ extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
268
+ extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
269
+ extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
270
+ extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
271
+ extern char *oj_longlong_to_string(long long num, bool negative, char *buf);
271
272
 
272
273
  extern void oj_str_writer_push_key(StrWriter sw, const char *key);
273
274
  extern void oj_str_writer_push_object(StrWriter sw, const char *key);
data/ext/oj/parse.c CHANGED
@@ -426,6 +426,7 @@ static void read_num(ParseInfo pi) {
426
426
  struct _numInfo ni;
427
427
  Val parent = stack_peek(&pi->stack);
428
428
 
429
+ ni.pi = pi;
429
430
  ni.str = pi->cur;
430
431
  ni.i = 0;
431
432
  ni.num = 0;
@@ -709,10 +710,7 @@ void oj_parse2(ParseInfo pi) {
709
710
  case '[': array_start(pi); break;
710
711
  case ']': array_end(pi); break;
711
712
  case ',': comma(pi); break;
712
- case '"':
713
- read_str(pi);
714
- break;
715
- // case '+':
713
+ case '"': read_str(pi); break;
716
714
  case '+':
717
715
  if (CompatMode == pi->options.mode) {
718
716
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
@@ -877,7 +875,7 @@ oj_num_as_value(NumInfo ni) {
877
875
  double d = strtod(ni->str, &end);
878
876
 
879
877
  if ((long)ni->len != (long)(end - ni->str)) {
880
- rb_raise(oj_parse_error_class, "Invalid float");
878
+ rb_raise(ni->pi->err_class, "Invalid float");
881
879
  }
882
880
  rnum = rb_float_new(d);
883
881
  }
data/ext/oj/parse.h CHANGED
@@ -16,22 +16,24 @@
16
16
  #include "val_stack.h"
17
17
 
18
18
  struct _rxClass;
19
+ struct _parseInfo;
19
20
 
20
21
  typedef struct _numInfo {
21
- int64_t i;
22
- int64_t num;
23
- int64_t div;
24
- int64_t di;
25
- const char *str;
26
- size_t len;
27
- long exp;
28
- int big;
29
- int infinity;
30
- int nan;
31
- int neg;
32
- int has_exp;
33
- int no_big;
34
- int bigdec_load;
22
+ int64_t i;
23
+ int64_t num;
24
+ int64_t div;
25
+ int64_t di;
26
+ const char *str;
27
+ size_t len;
28
+ long exp;
29
+ struct _parseInfo *pi;
30
+ int big;
31
+ int infinity;
32
+ int nan;
33
+ int neg;
34
+ int has_exp;
35
+ int no_big;
36
+ int bigdec_load;
35
37
  } *NumInfo;
36
38
 
37
39
  typedef struct _parseInfo {
data/ext/oj/parser.h CHANGED
@@ -32,9 +32,9 @@ typedef struct _num {
32
32
  long double dub;
33
33
  int64_t fixnum; // holds all digits
34
34
  uint32_t len;
35
- int16_t div; // 10^div
35
+ int16_t div; // 10^div
36
36
  int16_t exp;
37
- uint8_t shift; // shift of fixnum to get decimal
37
+ uint8_t shift; // shift of fixnum to get decimal
38
38
  bool neg;
39
39
  bool exp_neg;
40
40
  // for numbers as strings, reuse buf
data/ext/oj/reader.c CHANGED
@@ -101,7 +101,7 @@ int oj_reader_read(Reader reader) {
101
101
  } else {
102
102
  shift = reader->pro - reader->head - 1; // leave one character so we can backup one
103
103
  }
104
- if (0 >= shift) { /* no space left so allocate more */
104
+ if (0 >= shift) { /* no space left so allocate more */
105
105
  const char *old = reader->head;
106
106
  size_t size = reader->end - reader->head + BUF_PAD;
107
107
 
@@ -164,7 +164,6 @@ static VALUE partial_io_cb(VALUE rbuf) {
164
164
  }
165
165
  str = StringValuePtr(rstr);
166
166
  cnt = RSTRING_LEN(rstr);
167
- // printf("*** partial read %lu bytes, str: '%s'\n", cnt, str);
168
167
  strcpy(reader->tail, str);
169
168
  reader->read_end = reader->tail + cnt;
170
169
 
@@ -185,7 +184,6 @@ static VALUE io_cb(VALUE rbuf) {
185
184
  }
186
185
  str = StringValuePtr(rstr);
187
186
  cnt = RSTRING_LEN(rstr);
188
- // printf("*** read %lu bytes, str: '%s'\n", cnt, str);
189
187
  strcpy(reader->tail, str);
190
188
  reader->read_end = reader->tail + cnt;
191
189
 
data/ext/oj/saj.c CHANGED
@@ -587,7 +587,7 @@ static void saj_parse(VALUE handler, char *json) {
587
587
  if (0 == getrlimit(RLIMIT_STACK, &lim) && RLIM_INFINITY != lim.rlim_cur) {
588
588
  pi.stack_min = (void *)((char *)&obj - (lim.rlim_cur / 4 * 3)); /* let 3/4ths of the stack be used only */
589
589
  } else {
590
- pi.stack_min = 0; /* indicates not to check stack limit */
590
+ pi.stack_min = 0; /* indicates not to check stack limit */
591
591
  }
592
592
  }
593
593
  #endif
@@ -1,15 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/time'
2
4
 
3
5
  module Oj
4
-
5
6
  # Exists only to handle the ActiveSupport::TimeWithZone.
6
7
  class ActiveSupportHelper
7
-
8
8
  def self.createTimeWithZone(utc, zone)
9
9
  ActiveSupport::TimeWithZone.new(utc - utc.gmt_offset, ActiveSupport::TimeZone[zone])
10
10
  end
11
11
  end
12
-
13
12
  end
14
13
 
15
14
  Oj.register_odd(ActiveSupport::TimeWithZone, Oj::ActiveSupportHelper, :createTimeWithZone, :utc, 'time_zone.name')
data/lib/oj/json.rb CHANGED
@@ -1,178 +1,185 @@
1
1
  require 'ostruct'
2
2
  require 'oj/state'
3
3
 
4
- module JSON
5
- NaN = 0.0/0.0 unless defined?(::JSON::NaN)
6
- Infinity = 1.0/0.0 unless defined?(::JSON::Infinity)
7
- MinusInfinity = -1.0/0.0 unless defined?(::JSON::MinusInfinity)
8
- # Taken from the unit test. Note that items like check_circular? are not
9
- # present.
10
- PRETTY_STATE_PROTOTYPE = Ext::Generator::State.from_state({
11
- :allow_nan => false,
12
- :array_nl => "\n",
13
- :ascii_only => false,
14
- :buffer_initial_length => 1024,
15
- :depth => 0,
16
- :indent => " ",
17
- :max_nesting => 100,
18
- :object_nl => "\n",
19
- :space => " ",
20
- :space_before => "",
21
- }) unless defined?(::JSON::PRETTY_STATE_PROTOTYPE)
22
- SAFE_STATE_PROTOTYPE = Ext::Generator::State.from_state({
23
- :allow_nan => false,
24
- :array_nl => "",
25
- :ascii_only => false,
26
- :buffer_initial_length => 1024,
27
- :depth => 0,
28
- :indent => "",
29
- :max_nesting => 100,
30
- :object_nl => "",
31
- :space => "",
32
- :space_before => "",
33
- }) unless defined?(::JSON::SAFE_STATE_PROTOTYPE)
34
- FAST_STATE_PROTOTYPE = Ext::Generator::State.from_state({
35
- :allow_nan => false,
36
- :array_nl => "",
37
- :ascii_only => false,
38
- :buffer_initial_length => 1024,
39
- :depth => 0,
40
- :indent => "",
41
- :max_nesting => 0,
42
- :object_nl => "",
43
- :space => "",
44
- :space_before => "",
45
- }) unless defined?(::JSON::FAST_STATE_PROTOTYPE)
46
-
47
- def self.dump_default_options
48
- Oj::MimicDumpOption.new
49
- end
50
-
51
- def self.dump_default_options=(h)
52
- m = Oj::MimicDumpOption.new
53
- h.each do |k, v|
54
- m[k] = v
4
+ if defined?(JSON::PRETTY_STATE_PROTOTYPE)
5
+ warn "WARNING: oj/json is a compatability shim used by Oj. Requiring the file explicitly is no recommended."
6
+ end
7
+
8
+ unless defined?(JSON::PRETTY_STATE_PROTOTYPE)
9
+ module JSON
10
+ NaN = 0.0/0.0 unless defined?(::JSON::NaN)
11
+ Infinity = 1.0/0.0 unless defined?(::JSON::Infinity)
12
+ MinusInfinity = -1.0/0.0 unless defined?(::JSON::MinusInfinity)
13
+ # Taken from the unit test. Note that items like check_circular? are not
14
+ # present.
15
+ PRETTY_STATE_PROTOTYPE = Ext::Generator::State.from_state({
16
+ :allow_nan => false,
17
+ :array_nl => "\n",
18
+ :ascii_only => false,
19
+ :buffer_initial_length => 1024,
20
+ :depth => 0,
21
+ :indent => " ",
22
+ :max_nesting => 100,
23
+ :object_nl => "\n",
24
+ :space => " ",
25
+ :space_before => "",
26
+ }) unless defined?(::JSON::PRETTY_STATE_PROTOTYPE)
27
+ SAFE_STATE_PROTOTYPE = Ext::Generator::State.from_state({
28
+ :allow_nan => false,
29
+ :array_nl => "",
30
+ :ascii_only => false,
31
+ :buffer_initial_length => 1024,
32
+ :depth => 0,
33
+ :indent => "",
34
+ :max_nesting => 100,
35
+ :object_nl => "",
36
+ :space => "",
37
+ :space_before => "",
38
+ }) unless defined?(::JSON::SAFE_STATE_PROTOTYPE)
39
+ FAST_STATE_PROTOTYPE = Ext::Generator::State.from_state({
40
+ :allow_nan => false,
41
+ :array_nl => "",
42
+ :ascii_only => false,
43
+ :buffer_initial_length => 1024,
44
+ :depth => 0,
45
+ :indent => "",
46
+ :max_nesting => 0,
47
+ :object_nl => "",
48
+ :space => "",
49
+ :space_before => "",
50
+ }) unless defined?(::JSON::FAST_STATE_PROTOTYPE)
51
+
52
+ def self.dump_default_options
53
+ Oj::MimicDumpOption.new
55
54
  end
56
- end
57
55
 
58
- def self.parser=(p)
59
- @@parser = p
60
- end
56
+ def self.dump_default_options=(h)
57
+ m = Oj::MimicDumpOption.new
58
+ h.each do |k, v|
59
+ m[k] = v
60
+ end
61
+ end
61
62
 
62
- def self.parser()
63
- @@parser
64
- end
63
+ def self.parser=(p)
64
+ @@parser = p
65
+ end
65
66
 
66
- def self.generator=(g)
67
- @@generator = g
68
- end
67
+ def self.parser()
68
+ @@parser
69
+ end
69
70
 
70
- def self.generator()
71
- @@generator
72
- end
71
+ def self.generator=(g)
72
+ @@generator = g
73
+ end
73
74
 
74
- module Ext
75
- class Parser
76
- def initialize(src)
77
- raise TypeError.new("already initialized") unless @source.nil?
75
+ def self.generator()
76
+ @@generator
77
+ end
78
78
 
79
- @source = src
80
- end
79
+ module Ext
80
+ class Parser
81
+ def initialize(src)
82
+ raise TypeError.new("already initialized") unless @source.nil?
81
83
 
82
- def source()
83
- raise TypeError.new("already initialized") if @source.nil?
84
+ @source = src
85
+ end
84
86
 
85
- @source
86
- end
87
-
88
- def parse()
89
- raise TypeError.new("already initialized") if @source.nil?
87
+ def source()
88
+ raise TypeError.new("already initialized") if @source.nil?
90
89
 
91
- JSON.parse(@source)
92
- end
93
-
94
- end # Parser
95
- end # Ext
96
-
97
- State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
98
-
99
- begin
100
- send(:remove_const, :Parser)
101
- rescue
102
- end
103
- Parser = ::JSON::Ext::Parser unless defined?(::JSON::Parser)
104
- self.parser = ::JSON::Ext::Parser
105
- self.generator = ::JSON::Ext::Generator
106
-
107
- # Taken directly from the json gem. Shamelessly copied. It is similar in
108
- # some ways to the Oj::Bag class or the Oj::EasyHash class.
109
- class GenericObject < OpenStruct
110
- class << self
111
- alias [] new
112
-
113
- def json_creatable?
114
- @json_creatable
115
- end
90
+ @source
91
+ end
116
92
 
117
- attr_writer :json_creatable
93
+ def parse()
94
+ raise TypeError.new("already initialized") if @source.nil?
118
95
 
119
- def json_create(data)
120
- data = data.dup
121
- data.delete JSON.create_id
122
- self[data]
123
- end
96
+ JSON.parse(@source)
97
+ end
124
98
 
125
- def from_hash(object)
126
- case
127
- when object.respond_to?(:to_hash)
128
- result = new
129
- object.to_hash.each do |key, value|
130
- result[key] = from_hash(value)
99
+ end # Parser
100
+ end # Ext
101
+
102
+ State = ::JSON::Ext::Generator::State unless defined?(::JSON::State)
103
+
104
+ begin
105
+ send(:remove_const, :Parser)
106
+ rescue
107
+ # ignore and move on
108
+ end
109
+ Parser = ::JSON::Ext::Parser unless defined?(::JSON::Parser)
110
+ self.parser = ::JSON::Ext::Parser
111
+ self.generator = ::JSON::Ext::Generator
112
+
113
+ # Taken directly from the json gem. Shamelessly copied. It is similar in
114
+ # some ways to the Oj::Bag class or the Oj::EasyHash class.
115
+ class GenericObject < OpenStruct
116
+ class << self
117
+ alias [] new
118
+
119
+ def json_creatable?
120
+ @json_creatable
121
+ end
122
+
123
+ attr_writer :json_creatable
124
+
125
+ def json_create(data)
126
+ data = data.dup
127
+ data.delete JSON.create_id
128
+ self[data]
129
+ end
130
+
131
+ def from_hash(object)
132
+ case
133
+ when object.respond_to?(:to_hash)
134
+ result = new
135
+ object.to_hash.each do |key, value|
136
+ result[key] = from_hash(value)
137
+ end
138
+ result
139
+ when object.respond_to?(:to_ary)
140
+ object.to_ary.map { |a| from_hash(a) }
141
+ else
142
+ object
131
143
  end
132
- result
133
- when object.respond_to?(:to_ary)
134
- object.to_ary.map { |a| from_hash(a) }
135
- else
136
- object
137
144
  end
138
- end
139
145
 
140
- def load(source, proc = nil, opts = {})
141
- result = ::JSON.load(source, proc, opts.merge(:object_class => self))
142
- result.nil? ? new : result
143
- end
146
+ def load(source, proc = nil, opts = {})
147
+ result = ::JSON.load(source, proc, opts.merge(:object_class => self))
148
+ result.nil? ? new : result
149
+ end
144
150
 
145
- def dump(obj, *args)
146
- ::JSON.dump(obj, *args)
147
- end
151
+ def dump(obj, *args)
152
+ ::JSON.dump(obj, *args)
153
+ end
148
154
 
149
- end # self
155
+ end # self
150
156
 
151
- self.json_creatable = false
157
+ self.json_creatable = false
152
158
 
153
- def to_hash
154
- table
155
- end
159
+ def to_hash
160
+ table
161
+ end
156
162
 
157
- def [](name)
158
- __send__(name)
159
- end unless method_defined?(:[])
163
+ def [](name)
164
+ __send__(name)
165
+ end unless method_defined?(:[])
160
166
 
161
- def []=(name, value)
162
- __send__("#{name}=", value)
163
- end unless method_defined?(:[]=)
167
+ def []=(name, value)
168
+ __send__("#{name}=", value)
169
+ end unless method_defined?(:[]=)
164
170
 
165
- def |(other)
166
- self.class[other.to_hash.merge(to_hash)]
167
- end
171
+ def |(other)
172
+ self.class[other.to_hash.merge(to_hash)]
173
+ end
168
174
 
169
- def as_json(*)
170
- { JSON.create_id => self.class.name }.merge to_hash
171
- end
175
+ def as_json(*)
176
+ { JSON.create_id => self.class.name }.merge to_hash
177
+ end
172
178
 
173
- def to_json(*a)
174
- as_json.to_json(*a)
179
+ def to_json(*a)
180
+ as_json.to_json(*a)
181
+ end
175
182
  end
176
- end
177
-
178
- end # JSON
183
+
184
+ end # JSON
185
+ end
data/lib/oj/mimic.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: false
2
+
1
3
  require 'bigdecimal'
2
4
  begin
3
5
  require 'ostruct'
@@ -266,7 +268,7 @@ module Oj
266
268
  end
267
269
  end
268
270
  def self.json_create(h)
269
- if usec = h.delete('u')
271
+ if (usec = h.delete('u'))
270
272
  h['n'] = usec * 1000
271
273
  end
272
274
  if instance_methods.include?(:tv_nsec)
data/lib/oj/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Oj
2
2
  # Current version of the module.
3
- VERSION = '3.15.0'
3
+ VERSION = '3.15.1'
4
4
  end
data/test/foo.rb CHANGED
@@ -5,11 +5,16 @@ $LOAD_PATH << '.'
5
5
  $LOAD_PATH << File.join(__dir__, '../lib')
6
6
  $LOAD_PATH << File.join(__dir__, '../ext')
7
7
 
8
+ require 'active_support'
9
+ require 'json'
8
10
  require 'oj'
9
11
 
10
- GC.stress = true
12
+ Oj.mimic_JSON()
13
+ # Oj::Rails.mimic_JSON()
11
14
 
12
- Oj.mimic_JSON
13
-
14
- Oj.add_to_json(Hash)
15
- pp JSON('{ "a": 1, "b": 2 }', :object_class => JSON::GenericObject)
15
+ begin
16
+ ::JSON.parse('{ "foo": 84e }')
17
+ #::JSON.parse('{ "foo": 84eb234 }')
18
+ rescue Exception => e
19
+ puts "#{e.class}: #{e.message}"
20
+ end
data/test/perf_dump.rb CHANGED
@@ -24,8 +24,8 @@ opts.parse(ARGV)
24
24
  @obj = {
25
25
  'a' => 'Alpha', # string
26
26
  'b' => true, # boolean
27
- 'c' => 12345, # number
28
- 'd' => [ true, [false, [-123456789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
27
+ 'c' => 12_345, # number
28
+ 'd' => [ true, [false, [-123_456_789, nil], 3.9676, ['Something else.', false], nil]], # mix it up array
29
29
  'e' => { 'zero' => nil, 'one' => 1, 'two' => 2, 'three' => [3], 'four' => [0, 1, 2, 3, 4] }, # hash
30
30
  'f' => nil, # nil
31
31
  'h' => { 'a' => { 'b' => { 'c' => { 'd' => {'e' => { 'f' => { 'g' => nil }}}}}}}, # deep hash, not that deep
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.15.0
4
+ version: 3.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-03 00:00:00.000000000 Z
11
+ date: 2023-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest