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 +6 -2
- data/ext/oj/oj.c +10 -1
- data/ext/oj/oj.h +1 -0
- data/ext/oj/parse.c +7 -2
- data/ext/oj/sparse.c +8 -2
- data/lib/oj/version.rb +1 -1
- data/test/test_various.rb +22 -0
- metadata +2 -2
    
        data/README.md
    CHANGED
    
    | @@ -170,9 +170,13 @@ Oj.default_options = {:mode => :compat } | |
| 170 170 |  | 
| 171 171 | 
             
            ## Releases
         | 
| 172 172 |  | 
| 173 | 
            -
            **Release 2. | 
| 173 | 
            +
            **Release 2.16.0**
         | 
| 174 174 |  | 
| 175 | 
            -
             -  | 
| 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 |  | 
    
        data/ext/oj/oj.c
    CHANGED
    
    | @@ -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")); | 
| 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);
         | 
    
        data/ext/oj/oj.h
    CHANGED
    
    | @@ -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
         | 
    
        data/ext/oj/parse.c
    CHANGED
    
    | @@ -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 ( | 
| 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 ( | 
| 461 | 
            +
            		if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
         | 
| 457 462 | 
             
            		    ni.big = 1;
         | 
| 458 463 | 
             
            		}
         | 
| 459 464 | 
             
            	    }
         | 
    
        data/ext/oj/sparse.c
    CHANGED
    
    | @@ -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 ( | 
| 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 ( | 
| 465 | 
            +
            		if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
         | 
| 460 466 | 
             
            		    ni.big = 1;
         | 
| 461 467 | 
             
            		}
         | 
| 462 468 | 
             
            	    }
         | 
    
        data/lib/oj/version.rb
    CHANGED
    
    
    
        data/test/test_various.rb
    CHANGED
    
    | @@ -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. | 
| 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- | 
| 12 | 
            +
            date: 2016-06-19 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rake-compiler
         |