oj 2.15.1 → 2.16.0

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