oj 2.15.1 → 2.16.0

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/README.md CHANGED
@@ -170,9 +170,13 @@ Oj.default_options = {:mode => :compat }
170
170
 
171
171
  ## Releases
172
172
 
173
- **Release 2.15.1**
173
+ **Release 2.16.0**
174
174
 
175
- - Fixed bug with activerecord when to_json returns an array instead of a string.
175
+ - Added option to allow invalid unicode characters. This is not a suggested
176
+ option in a majority of the cases.
177
+
178
+ - Fixed float parsing for 32 bit systems so that it does not roll over to
179
+ BigDecimal until more than 15 significant digits.
176
180
 
177
181
  [Older release notes](http://www.ohler.com/dev/oj_misc/release_notes.html).
178
182
 
@@ -106,6 +106,7 @@ VALUE oj_struct_class;
106
106
  VALUE oj_slash_string;
107
107
 
108
108
  static VALUE allow_gc_sym;
109
+ static VALUE allow_invalid_unicode_sym;
109
110
  static VALUE ascii_only_sym;
110
111
  static VALUE ascii_sym;
111
112
  static VALUE auto_define_sym;
@@ -181,6 +182,7 @@ struct _Options oj_default_options = {
181
182
  No, // nilnil
182
183
  Yes, // allow_gc
183
184
  Yes, // quirks_mode
185
+ No, // allow_invalid
184
186
  json_class, // create_id
185
187
  10, // create_id_len
186
188
  9, // sec_prec
@@ -224,6 +226,7 @@ static VALUE define_mimic_json(int argc, VALUE *argv, VALUE self);
224
226
  * - nilnil: [true|false|nil] if true a nil input to load will return nil and not raise an Exception
225
227
  * - allow_gc: [true|false|nil] allow or prohibit GC during parsing, default is true (allow)
226
228
  * - quirks_mode: [true,|false|nil] Allow single JSON values instead of documents, default is true (allow)
229
+ * - allow_invalid_unicode: [true,|false|nil] Allow invalid unicode, default is false (don't allow)
227
230
  * - indent_str: [String|nil] String to use for indentation, overriding the indent option is not nil
228
231
  * - space: [String|nil] String to use for the space after the colon in JSON object fields
229
232
  * - space_before: [String|nil] String to use before the colon separator in JSON object fields
@@ -251,6 +254,7 @@ get_def_opts(VALUE self) {
251
254
  rb_hash_aset(opts, nilnil_sym, (Yes == oj_default_options.nilnil) ? Qtrue : ((No == oj_default_options.nilnil) ? Qfalse : Qnil));
252
255
  rb_hash_aset(opts, allow_gc_sym, (Yes == oj_default_options.allow_gc) ? Qtrue : ((No == oj_default_options.allow_gc) ? Qfalse : Qnil));
253
256
  rb_hash_aset(opts, quirks_mode_sym, (Yes == oj_default_options.quirks_mode) ? Qtrue : ((No == oj_default_options.quirks_mode) ? Qfalse : Qnil));
257
+ rb_hash_aset(opts, allow_invalid_unicode_sym, (Yes == oj_default_options.allow_invalid) ? Qtrue : ((No == oj_default_options.allow_invalid) ? Qfalse : Qnil));
254
258
  rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
255
259
  switch (oj_default_options.mode) {
256
260
  case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
@@ -331,6 +335,7 @@ get_def_opts(VALUE self) {
331
335
  * @param [true|false|nil] :nilnil if true a nil input to load will return nil and not raise an Exception
332
336
  * @param [true|false|nil] :allow_gc allow or prohibit GC during parsing, default is true (allow)
333
337
  * @param [true|false|nil] :quirks_mode allow single JSON values instead of documents, default is true (allow)
338
+ * @param [true|false|nil] :allow_invalid_unicode allow invalid unicode, default is false (don't allow)
334
339
  * @param [String|nil] :space String to use for the space after the colon in JSON object fields
335
340
  * @param [String|nil] :space_before String to use before the colon separator in JSON object fields
336
341
  * @param [String|nil] :object_nl String to use after a JSON object field value
@@ -358,6 +363,7 @@ oj_parse_options(VALUE ropts, Options copts) {
358
363
  { nilnil_sym, &copts->nilnil },
359
364
  { allow_gc_sym, &copts->allow_gc },
360
365
  { quirks_mode_sym, &copts->quirks_mode },
366
+ { allow_invalid_unicode_sym, &copts->allow_invalid },
361
367
  { Qnil, 0 }
362
368
  };
363
369
  YesNoOpt o;
@@ -1765,6 +1771,7 @@ mimic_parse(int argc, VALUE *argv, VALUE self) {
1765
1771
  pi.options = oj_default_options;
1766
1772
  pi.options.auto_define = No;
1767
1773
  pi.options.quirks_mode = No;
1774
+ pi.options.allow_invalid = No;
1768
1775
 
1769
1776
  if (2 <= argc) {
1770
1777
  VALUE ropts = argv[1];
@@ -1845,6 +1852,7 @@ static struct _Options mimic_object_to_json_options = {
1845
1852
  Yes, // nilnil
1846
1853
  Yes, // allow_gc
1847
1854
  Yes, // quirks_mode
1855
+ No, // allow_invalid
1848
1856
  json_class, // create_id
1849
1857
  10, // create_id_len
1850
1858
  9, // sec_prec
@@ -2170,13 +2178,14 @@ void Init_oj() {
2170
2178
  indent_sym = ID2SYM(rb_intern("indent")); rb_gc_register_address(&indent_sym);
2171
2179
  json_sym = ID2SYM(rb_intern("json")); rb_gc_register_address(&json_sym);
2172
2180
  mode_sym = ID2SYM(rb_intern("mode")); rb_gc_register_address(&mode_sym);
2173
- nan_sym = ID2SYM(rb_intern("nan")); rb_gc_register_address(&nan_sym);
2181
+ nan_sym = ID2SYM(rb_intern("nan")); rb_gc_register_address(&nan_sym);
2174
2182
  newline_sym = ID2SYM(rb_intern("newline")); rb_gc_register_address(&newline_sym);
2175
2183
  nilnil_sym = ID2SYM(rb_intern("nilnil")); rb_gc_register_address(&nilnil_sym);
2176
2184
  null_sym = ID2SYM(rb_intern("null")); rb_gc_register_address(&null_sym);
2177
2185
  object_nl_sym = ID2SYM(rb_intern("object_nl")); rb_gc_register_address(&object_nl_sym);
2178
2186
  object_sym = ID2SYM(rb_intern("object")); rb_gc_register_address(&object_sym);
2179
2187
  quirks_mode_sym = ID2SYM(rb_intern("quirks_mode")); rb_gc_register_address(&quirks_mode_sym);
2188
+ allow_invalid_unicode_sym = ID2SYM(rb_intern("allow_invalid_unicode"));rb_gc_register_address(&allow_invalid_unicode_sym);
2180
2189
  raise_sym = ID2SYM(rb_intern("raise")); rb_gc_register_address(&raise_sym);
2181
2190
  ruby_sym = ID2SYM(rb_intern("ruby")); rb_gc_register_address(&ruby_sym);
2182
2191
  sec_prec_sym = ID2SYM(rb_intern("second_precision"));rb_gc_register_address(&sec_prec_sym);
@@ -156,6 +156,7 @@ typedef struct _Options {
156
156
  char nilnil; // YesNo
157
157
  char allow_gc; // allow GC during parse
158
158
  char quirks_mode; // allow single JSON values instead of documents
159
+ char allow_invalid; // YesNo - allow invalid unicode
159
160
  const char *create_id; // 0 or string
160
161
  size_t create_id_len; // length of create_id
161
162
  int sec_prec; // second precision when dumping time
@@ -255,6 +255,11 @@ read_escaped_str(ParseInfo pi, const char *start) {
255
255
 
256
256
  s++;
257
257
  if ('\\' != *s || 'u' != *(s + 1)) {
258
+ if (Yes == pi->options.allow_invalid) {
259
+ s--;
260
+ unicode_to_chars(pi, &buf, code);
261
+ break;
262
+ }
258
263
  pi->cur = s;
259
264
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid escaped character");
260
265
  buf_cleanup(&buf);
@@ -437,7 +442,7 @@ read_num(ParseInfo pi) {
437
442
  int d = (*pi->cur - '0');
438
443
 
439
444
  ni.i = ni.i * 10 + d;
440
- if (LONG_MAX <= ni.i || DEC_MAX < dec_cnt) {
445
+ if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
441
446
  ni.big = 1;
442
447
  }
443
448
  }
@@ -453,7 +458,7 @@ read_num(ParseInfo pi) {
453
458
  ni.num = ni.num * 10 + d;
454
459
  ni.div *= 10;
455
460
  ni.di++;
456
- if (LONG_MAX <= ni.div || DEC_MAX < dec_cnt) {
461
+ if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
457
462
  ni.big = 1;
458
463
  }
459
464
  }
@@ -265,6 +265,12 @@ read_escaped_str(ParseInfo pi) {
265
265
  c = reader_get(&pi->rd);
266
266
  ch2 = reader_get(&pi->rd);
267
267
  if ('\\' != c || 'u' != ch2) {
268
+ if (Yes == pi->options.allow_invalid) {
269
+ unicode_to_chars(pi, &buf, code);
270
+ reader_backup(&pi->rd);
271
+ reader_backup(&pi->rd);
272
+ break;
273
+ }
268
274
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "invalid escaped character");
269
275
  buf_cleanup(&buf);
270
276
  return;
@@ -440,7 +446,7 @@ read_num(ParseInfo pi) {
440
446
  int d = (c - '0');
441
447
 
442
448
  ni.i = ni.i * 10 + d;
443
- if (LONG_MAX <= ni.i || DEC_MAX < dec_cnt) {
449
+ if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
444
450
  ni.big = 1;
445
451
  }
446
452
  }
@@ -456,7 +462,7 @@ read_num(ParseInfo pi) {
456
462
  ni.num = ni.num * 10 + d;
457
463
  ni.div *= 10;
458
464
  ni.di++;
459
- if (LONG_MAX <= ni.div || DEC_MAX < dec_cnt) {
465
+ if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
460
466
  ni.big = 1;
461
467
  }
462
468
  }
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '2.15.1'
4
+ VERSION = '2.16.0'
5
5
  end
@@ -106,6 +106,7 @@ class Juice < Minitest::Test
106
106
  :nilnil=>false,
107
107
  :allow_gc=>true,
108
108
  :quirks_mode=>true,
109
+ :allow_invalid_unicode=>false,
109
110
  :float_precision=>15,
110
111
  :mode=>:object,
111
112
  :escape_mode=>:json,
@@ -128,6 +129,7 @@ class Juice < Minitest::Test
128
129
  :nilnil=>true,
129
130
  :allow_gc=>false,
130
131
  :quirks_mode=>false,
132
+ :allow_invalid_unicode=>true,
131
133
  :float_precision=>13,
132
134
  :mode=>:strict,
133
135
  :escape_mode=>:ascii,
@@ -288,6 +290,26 @@ class Juice < Minitest::Test
288
290
  assert_equal(json, json2)
289
291
  end
290
292
 
293
+ def test_invalid_unicode_raise
294
+ # validate that an invalid unicode raises unless the :allow_invalid_unicode is true
295
+ json = %{"x\\ud83dy"}
296
+ begin
297
+ obj = Oj.load(json)
298
+ rescue Exception
299
+ assert(true)
300
+ return
301
+ end
302
+ assert(false, "*** expected an exception")
303
+ end
304
+
305
+ def test_invalid_unicode_ok
306
+ # validate that an invalid unicode raises unless the :allow_invalid_unicode is true
307
+ json = %{"x\\ud83dy"}
308
+ obj = Oj.load(json, :allow_invalid_unicode => true)
309
+ # The same as what ruby would do with the invalid encoding.
310
+ assert_equal("x\xED\xA0\xBDy", obj.to_s)
311
+ end
312
+
291
313
  def test_dump_options
292
314
  json = Oj.dump({ 'a' => 1, 'b' => [true, false]},
293
315
  :mode => :compat,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.15.1
4
+ version: 2.16.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-26 00:00:00.000000000 Z
12
+ date: 2016-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler