oj 3.13.23 → 3.16.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 +4 -4
 - data/CHANGELOG.md +81 -0
 - data/README.md +2 -2
 - data/ext/oj/buf.h +7 -6
 - data/ext/oj/cache.c +29 -26
 - data/ext/oj/cache.h +3 -2
 - data/ext/oj/cache8.c +10 -9
 - data/ext/oj/circarray.c +7 -5
 - data/ext/oj/circarray.h +2 -2
 - data/ext/oj/code.c +5 -12
 - data/ext/oj/code.h +2 -2
 - data/ext/oj/compat.c +20 -60
 - data/ext/oj/custom.c +26 -59
 - data/ext/oj/debug.c +3 -9
 - data/ext/oj/dump.c +103 -53
 - data/ext/oj/dump.h +1 -4
 - data/ext/oj/dump_compat.c +557 -592
 - data/ext/oj/dump_leaf.c +3 -5
 - data/ext/oj/dump_object.c +42 -48
 - data/ext/oj/dump_strict.c +10 -22
 - data/ext/oj/encoder.c +1 -1
 - data/ext/oj/err.c +2 -13
 - data/ext/oj/err.h +9 -12
 - data/ext/oj/extconf.rb +16 -7
 - data/ext/oj/fast.c +60 -92
 - data/ext/oj/intern.c +62 -47
 - data/ext/oj/intern.h +3 -7
 - data/ext/oj/mem.c +318 -0
 - data/ext/oj/mem.h +53 -0
 - data/ext/oj/mimic_json.c +51 -32
 - data/ext/oj/object.c +33 -43
 - data/ext/oj/odd.c +8 -6
 - data/ext/oj/odd.h +4 -4
 - data/ext/oj/oj.c +243 -212
 - data/ext/oj/oj.h +83 -81
 - data/ext/oj/parse.c +94 -148
 - data/ext/oj/parse.h +21 -24
 - data/ext/oj/parser.c +80 -67
 - data/ext/oj/parser.h +7 -8
 - data/ext/oj/rails.c +70 -92
 - data/ext/oj/reader.c +9 -14
 - data/ext/oj/reader.h +4 -2
 - data/ext/oj/resolve.c +3 -4
 - data/ext/oj/rxclass.c +6 -5
 - data/ext/oj/rxclass.h +1 -1
 - data/ext/oj/saj.c +10 -9
 - data/ext/oj/saj2.c +37 -49
 - data/ext/oj/saj2.h +1 -1
 - data/ext/oj/scp.c +3 -14
 - data/ext/oj/sparse.c +22 -70
 - data/ext/oj/stream_writer.c +45 -41
 - data/ext/oj/strict.c +20 -52
 - data/ext/oj/string_writer.c +64 -38
 - data/ext/oj/trace.h +31 -4
 - data/ext/oj/usual.c +125 -114
 - data/ext/oj/usual.h +7 -6
 - data/ext/oj/util.h +1 -1
 - data/ext/oj/val_stack.c +13 -2
 - data/ext/oj/val_stack.h +8 -7
 - data/ext/oj/wab.c +25 -57
 - data/lib/oj/active_support_helper.rb +1 -3
 - data/lib/oj/bag.rb +7 -1
 - data/lib/oj/easy_hash.rb +4 -5
 - data/lib/oj/error.rb +0 -1
 - data/lib/oj/json.rb +162 -150
 - data/lib/oj/mimic.rb +7 -7
 - data/lib/oj/schandler.rb +5 -4
 - data/lib/oj/state.rb +8 -5
 - data/lib/oj/version.rb +1 -2
 - data/lib/oj.rb +2 -0
 - data/pages/InstallOptions.md +20 -0
 - data/pages/Options.md +4 -0
 - data/test/_test_active.rb +8 -9
 - data/test/_test_active_mimic.rb +7 -8
 - data/test/_test_mimic_rails.rb +17 -20
 - data/test/activerecord/result_test.rb +5 -6
 - data/test/activesupport6/encoding_test.rb +63 -28
 - data/test/activesupport7/abstract_unit.rb +4 -1
 - data/test/activesupport7/encoding_test.rb +72 -22
 - data/test/files.rb +15 -15
 - data/test/foo.rb +18 -69
 - data/test/helper.rb +5 -8
 - data/test/isolated/shared.rb +3 -2
 - data/test/json_gem/json_addition_test.rb +2 -2
 - data/test/json_gem/json_common_interface_test.rb +8 -6
 - data/test/json_gem/json_encoding_test.rb +0 -0
 - data/test/json_gem/json_ext_parser_test.rb +1 -0
 - data/test/json_gem/json_fixtures_test.rb +3 -2
 - data/test/json_gem/json_generator_test.rb +50 -33
 - data/test/json_gem/json_generic_object_test.rb +11 -11
 - data/test/json_gem/json_parser_test.rb +46 -46
 - data/test/json_gem/json_string_matching_test.rb +9 -9
 - data/test/mem.rb +13 -12
 - data/test/perf.rb +21 -26
 - data/test/perf_compat.rb +31 -33
 - data/test/perf_dump.rb +28 -28
 - data/test/perf_fast.rb +80 -82
 - data/test/perf_file.rb +27 -29
 - data/test/perf_object.rb +65 -69
 - data/test/perf_once.rb +12 -11
 - data/test/perf_parser.rb +42 -48
 - data/test/perf_saj.rb +46 -54
 - data/test/perf_scp.rb +57 -69
 - data/test/perf_simple.rb +41 -39
 - data/test/perf_strict.rb +68 -70
 - data/test/perf_wab.rb +67 -69
 - data/test/prec.rb +5 -5
 - data/test/sample/change.rb +0 -1
 - data/test/sample/dir.rb +0 -1
 - data/test/sample/doc.rb +0 -1
 - data/test/sample/file.rb +0 -1
 - data/test/sample/group.rb +0 -1
 - data/test/sample/hasprops.rb +0 -1
 - data/test/sample/layer.rb +0 -1
 - data/test/sample/rect.rb +0 -1
 - data/test/sample/shape.rb +0 -1
 - data/test/sample/text.rb +0 -1
 - data/test/sample.rb +16 -16
 - data/test/sample_json.rb +8 -8
 - data/test/test_compat.rb +81 -54
 - data/test/test_custom.rb +63 -52
 - data/test/test_debian.rb +7 -10
 - data/test/test_fast.rb +86 -90
 - data/test/test_file.rb +24 -29
 - data/test/test_gc.rb +5 -5
 - data/test/test_generate.rb +5 -5
 - data/test/test_hash.rb +4 -4
 - data/test/test_integer_range.rb +9 -9
 - data/test/test_null.rb +20 -20
 - data/test/test_object.rb +92 -87
 - data/test/test_parser.rb +4 -4
 - data/test/test_parser_debug.rb +5 -5
 - data/test/test_parser_saj.rb +27 -25
 - data/test/test_parser_usual.rb +44 -6
 - data/test/test_rails.rb +2 -2
 - data/test/test_saj.rb +10 -8
 - data/test/test_scp.rb +35 -35
 - data/test/test_strict.rb +38 -32
 - data/test/test_various.rb +146 -97
 - data/test/test_wab.rb +46 -44
 - data/test/test_writer.rb +63 -47
 - data/test/tests.rb +7 -7
 - data/test/tests_mimic.rb +6 -6
 - data/test/tests_mimic_addition.rb +6 -6
 - metadata +46 -26
 - data/test/activesupport4/decoding_test.rb +0 -108
 - data/test/activesupport4/encoding_test.rb +0 -531
 - data/test/activesupport4/test_helper.rb +0 -41
 - data/test/activesupport5/abstract_unit.rb +0 -45
 - data/test/activesupport5/decoding_test.rb +0 -133
 - data/test/activesupport5/encoding_test.rb +0 -500
 - data/test/activesupport5/encoding_test_cases.rb +0 -98
 - data/test/activesupport5/test_helper.rb +0 -72
 - data/test/activesupport5/time_zone_test_helpers.rb +0 -39
 - data/test/bar.rb +0 -11
 - data/test/baz.rb +0 -16
 - data/test/bug.rb +0 -16
 - data/test/zoo.rb +0 -13
 
    
        data/ext/oj/dump.c
    CHANGED
    
    | 
         @@ -15,6 +15,7 @@ 
     | 
|
| 
       15 
15 
     | 
    
         
             
            #endif
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
            #include "cache8.h"
         
     | 
| 
      
 18 
     | 
    
         
            +
            #include "mem.h"
         
     | 
| 
       18 
19 
     | 
    
         
             
            #include "odd.h"
         
     | 
| 
       19 
20 
     | 
    
         
             
            #include "oj.h"
         
     | 
| 
       20 
21 
     | 
    
         
             
            #include "trace.h"
         
     | 
| 
         @@ -197,7 +198,18 @@ inline static long rails_xss_friendly_size(const uint8_t *str, size_t len) { 
     | 
|
| 
       197 
198 
     | 
    
         
             
            }
         
     | 
| 
       198 
199 
     | 
    
         | 
| 
       199 
200 
     | 
    
         
             
            inline static size_t rails_friendly_size(const uint8_t *str, size_t len) {
         
     | 
| 
       200 
     | 
    
         
            -
                 
     | 
| 
      
 201 
     | 
    
         
            +
                long    size = 0;
         
     | 
| 
      
 202 
     | 
    
         
            +
                size_t  i    = len;
         
     | 
| 
      
 203 
     | 
    
         
            +
                uint8_t hi   = 0;
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                for (; 0 < i; str++, i--) {
         
     | 
| 
      
 206 
     | 
    
         
            +
                    size += rails_friendly_chars[*str];
         
     | 
| 
      
 207 
     | 
    
         
            +
                    hi |= *str & 0x80;
         
     | 
| 
      
 208 
     | 
    
         
            +
                }
         
     | 
| 
      
 209 
     | 
    
         
            +
                if (0 == hi) {
         
     | 
| 
      
 210 
     | 
    
         
            +
                    return size - len * (size_t)'0';
         
     | 
| 
      
 211 
     | 
    
         
            +
                }
         
     | 
| 
      
 212 
     | 
    
         
            +
                return -(size - len * (size_t)'0');
         
     | 
| 
       201 
213 
     | 
    
         
             
            }
         
     | 
| 
       202 
214 
     | 
    
         | 
| 
       203 
215 
     | 
    
         
             
            const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp) {
         
     | 
| 
         @@ -305,8 +317,8 @@ static const char *dump_unicode(const char *str, const char *end, Out out, const 
     | 
|
| 
       305 
317 
     | 
    
         
             
                    uint32_t c1;
         
     | 
| 
       306 
318 
     | 
    
         | 
| 
       307 
319 
     | 
    
         
             
                    code -= 0x00010000;
         
     | 
| 
       308 
     | 
    
         
            -
                    c1 
     | 
| 
       309 
     | 
    
         
            -
                    code 
     | 
| 
      
 320 
     | 
    
         
            +
                    c1   = ((code >> 10) & 0x000003FF) + 0x0000D800;
         
     | 
| 
      
 321 
     | 
    
         
            +
                    code = (code & 0x000003FF) + 0x0000DC00;
         
     | 
| 
       310 
322 
     | 
    
         
             
                    APPEND_CHARS(out->cur, "\\u", 2);
         
     | 
| 
       311 
323 
     | 
    
         
             
                    for (i = 3; 0 <= i; i--) {
         
     | 
| 
       312 
324 
     | 
    
         
             
                        *out->cur++ = hex_chars[(uint8_t)(c1 >> (i * 4)) & 0x0F];
         
     | 
| 
         @@ -463,7 +475,7 @@ void oj_dump_time(VALUE obj, Out out, int withZone) { 
     | 
|
| 
       463 
475 
     | 
    
         
             
            }
         
     | 
| 
       464 
476 
     | 
    
         | 
| 
       465 
477 
     | 
    
         
             
            void oj_dump_ruby_time(VALUE obj, Out out) {
         
     | 
| 
       466 
     | 
    
         
            -
                volatile VALUE rstr =  
     | 
| 
      
 478 
     | 
    
         
            +
                volatile VALUE rstr = oj_safe_string_convert(obj);
         
     | 
| 
       467 
479 
     | 
    
         | 
| 
       468 
480 
     | 
    
         
             
                oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
         
     | 
| 
       469 
481 
     | 
    
         
             
            }
         
     | 
| 
         @@ -609,7 +621,7 @@ void oj_write_obj_to_file(VALUE obj, const char *path, Options copts) { 
     | 
|
| 
       609 
621 
     | 
    
         | 
| 
       610 
622 
     | 
    
         
             
                oj_out_init(&out);
         
     | 
| 
       611 
623 
     | 
    
         | 
| 
       612 
     | 
    
         
            -
                out.omit_nil 
     | 
| 
      
 624 
     | 
    
         
            +
                out.omit_nil = copts->dump_opts.omit_nil;
         
     | 
| 
       613 
625 
     | 
    
         
             
                oj_dump_obj_to_json(obj, copts, &out);
         
     | 
| 
       614 
626 
     | 
    
         
             
                size = out.cur - out.buf;
         
     | 
| 
       615 
627 
     | 
    
         
             
                if (0 == (f = fopen(path, "w"))) {
         
     | 
| 
         @@ -657,7 +669,7 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) { 
     | 
|
| 
       657 
669 
     | 
    
         | 
| 
       658 
670 
     | 
    
         
             
                oj_out_init(&out);
         
     | 
| 
       659 
671 
     | 
    
         | 
| 
       660 
     | 
    
         
            -
                out.omit_nil 
     | 
| 
      
 672 
     | 
    
         
            +
                out.omit_nil = copts->dump_opts.omit_nil;
         
     | 
| 
       661 
673 
     | 
    
         
             
                oj_dump_obj_to_json(obj, copts, &out);
         
     | 
| 
       662 
674 
     | 
    
         
             
                size = out.cur - out.buf;
         
     | 
| 
       663 
675 
     | 
    
         
             
                if (oj_stringio_class == clas) {
         
     | 
| 
         @@ -697,7 +709,7 @@ void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       697 
709 
     | 
    
         | 
| 
       698 
710 
     | 
    
         
             
                if (oj_utf8_encoding_index != idx) {
         
     | 
| 
       699 
711 
     | 
    
         
             
                    rb_encoding *enc = rb_enc_from_index(idx);
         
     | 
| 
       700 
     | 
    
         
            -
                    obj 
     | 
| 
      
 712 
     | 
    
         
            +
                    obj              = rb_str_conv_enc(obj, enc, oj_utf8_encoding);
         
     | 
| 
       701 
713 
     | 
    
         
             
                }
         
     | 
| 
       702 
714 
     | 
    
         
             
                oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out);
         
     | 
| 
       703 
715 
     | 
    
         
             
            }
         
     | 
| 
         @@ -726,8 +738,11 @@ static void debug_raise(const char *orig, size_t cnt, int line) { 
     | 
|
| 
       726 
738 
     | 
    
         | 
| 
       727 
739 
     | 
    
         
             
            void oj_dump_raw_json(VALUE obj, int depth, Out out) {
         
     | 
| 
       728 
740 
     | 
    
         
             
                if (oj_string_writer_class == rb_obj_class(obj)) {
         
     | 
| 
       729 
     | 
    
         
            -
                    StrWriter sw 
     | 
| 
       730 
     | 
    
         
            -
                    size_t    len 
     | 
| 
      
 741 
     | 
    
         
            +
                    StrWriter sw;
         
     | 
| 
      
 742 
     | 
    
         
            +
                    size_t    len;
         
     | 
| 
      
 743 
     | 
    
         
            +
             
     | 
| 
      
 744 
     | 
    
         
            +
                    sw  = oj_str_writer_unwrap(obj);
         
     | 
| 
      
 745 
     | 
    
         
            +
                    len = sw->out.cur - sw->out.buf;
         
     | 
| 
       731 
746 
     | 
    
         | 
| 
       732 
747 
     | 
    
         
             
                    if (0 < len) {
         
     | 
| 
       733 
748 
     | 
    
         
             
                        len--;
         
     | 
| 
         @@ -736,13 +751,9 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) { 
     | 
|
| 
       736 
751 
     | 
    
         
             
                } else {
         
     | 
| 
       737 
752 
     | 
    
         
             
                    volatile VALUE jv;
         
     | 
| 
       738 
753 
     | 
    
         | 
| 
       739 
     | 
    
         
            -
                     
     | 
| 
       740 
     | 
    
         
            -
                        oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
         
     | 
| 
       741 
     | 
    
         
            -
                    }
         
     | 
| 
      
 754 
     | 
    
         
            +
                    TRACE(out->opts->trace, "raw_json", obj, depth + 1, TraceRubyIn);
         
     | 
| 
       742 
755 
     | 
    
         
             
                    jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
         
     | 
| 
       743 
     | 
    
         
            -
                     
     | 
| 
       744 
     | 
    
         
            -
                        oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
         
     | 
| 
       745 
     | 
    
         
            -
                    }
         
     | 
| 
      
 756 
     | 
    
         
            +
                    TRACE(out->opts->trace, "raw_json", obj, depth + 1, TraceRubyOut);
         
     | 
| 
       746 
757 
     | 
    
         
             
                    oj_dump_raw(RSTRING_PTR(jv), (size_t)RSTRING_LEN(jv), out);
         
     | 
| 
       747 
758 
     | 
    
         
             
                }
         
     | 
| 
       748 
759 
     | 
    
         
             
            }
         
     | 
| 
         @@ -750,8 +761,9 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) { 
     | 
|
| 
       750 
761 
     | 
    
         
             
            void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
         
     | 
| 
       751 
762 
     | 
    
         
             
                size_t      size;
         
     | 
| 
       752 
763 
     | 
    
         
             
                char       *cmap;
         
     | 
| 
       753 
     | 
    
         
            -
                const char *orig 
     | 
| 
       754 
     | 
    
         
            -
                bool        has_hi 
     | 
| 
      
 764 
     | 
    
         
            +
                const char *orig                  = str;
         
     | 
| 
      
 765 
     | 
    
         
            +
                bool        has_hi                = false;
         
     | 
| 
      
 766 
     | 
    
         
            +
                bool        do_unicode_validation = false;
         
     | 
| 
       755 
767 
     | 
    
         | 
| 
       756 
768 
     | 
    
         
             
                switch (out->opts->escape_mode) {
         
     | 
| 
       757 
769 
     | 
    
         
             
                case NLEsc:
         
     | 
| 
         @@ -764,16 +776,17 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou 
     | 
|
| 
       764 
776 
     | 
    
         
             
                    break;
         
     | 
| 
       765 
777 
     | 
    
         
             
                case SlashEsc:
         
     | 
| 
       766 
778 
     | 
    
         
             
                    has_hi = true;
         
     | 
| 
       767 
     | 
    
         
            -
                    cmap 
     | 
| 
       768 
     | 
    
         
            -
                    size 
     | 
| 
      
 779 
     | 
    
         
            +
                    cmap   = slash_friendly_chars;
         
     | 
| 
      
 780 
     | 
    
         
            +
                    size   = slash_friendly_size((uint8_t *)str, cnt);
         
     | 
| 
       769 
781 
     | 
    
         
             
                    break;
         
     | 
| 
       770 
782 
     | 
    
         
             
                case XSSEsc:
         
     | 
| 
       771 
783 
     | 
    
         
             
                    cmap = xss_friendly_chars;
         
     | 
| 
       772 
784 
     | 
    
         
             
                    size = xss_friendly_size((uint8_t *)str, cnt);
         
     | 
| 
       773 
785 
     | 
    
         
             
                    break;
         
     | 
| 
       774 
786 
     | 
    
         
             
                case JXEsc:
         
     | 
| 
       775 
     | 
    
         
            -
                    cmap 
     | 
| 
       776 
     | 
    
         
            -
                    size 
     | 
| 
      
 787 
     | 
    
         
            +
                    cmap                  = hixss_friendly_chars;
         
     | 
| 
      
 788 
     | 
    
         
            +
                    size                  = hixss_friendly_size((uint8_t *)str, cnt);
         
     | 
| 
      
 789 
     | 
    
         
            +
                    do_unicode_validation = true;
         
     | 
| 
       777 
790 
     | 
    
         
             
                    break;
         
     | 
| 
       778 
791 
     | 
    
         
             
                case RailsXEsc: {
         
     | 
| 
       779 
792 
     | 
    
         
             
                    long sz;
         
     | 
| 
         @@ -786,12 +799,22 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou 
     | 
|
| 
       786 
799 
     | 
    
         
             
                    } else {
         
     | 
| 
       787 
800 
     | 
    
         
             
                        size = (size_t)sz;
         
     | 
| 
       788 
801 
     | 
    
         
             
                    }
         
     | 
| 
      
 802 
     | 
    
         
            +
                    do_unicode_validation = true;
         
     | 
| 
       789 
803 
     | 
    
         
             
                    break;
         
     | 
| 
       790 
804 
     | 
    
         
             
                }
         
     | 
| 
       791 
     | 
    
         
            -
                case RailsEsc:
         
     | 
| 
      
 805 
     | 
    
         
            +
                case RailsEsc: {
         
     | 
| 
      
 806 
     | 
    
         
            +
                    long sz;
         
     | 
| 
       792 
807 
     | 
    
         
             
                    cmap = rails_friendly_chars;
         
     | 
| 
       793 
     | 
    
         
            -
                     
     | 
| 
      
 808 
     | 
    
         
            +
                    sz   = rails_friendly_size((uint8_t *)str, cnt);
         
     | 
| 
      
 809 
     | 
    
         
            +
                    if (sz < 0) {
         
     | 
| 
      
 810 
     | 
    
         
            +
                        has_hi = true;
         
     | 
| 
      
 811 
     | 
    
         
            +
                        size   = (size_t)-sz;
         
     | 
| 
      
 812 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 813 
     | 
    
         
            +
                        size = (size_t)sz;
         
     | 
| 
      
 814 
     | 
    
         
            +
                    }
         
     | 
| 
      
 815 
     | 
    
         
            +
                    do_unicode_validation = true;
         
     | 
| 
       794 
816 
     | 
    
         
             
                    break;
         
     | 
| 
      
 817 
     | 
    
         
            +
                }
         
     | 
| 
       795 
818 
     | 
    
         
             
                case JSONEsc:
         
     | 
| 
       796 
819 
     | 
    
         
             
                default: cmap = hibit_friendly_chars; size = hibit_friendly_size((uint8_t *)str, cnt);
         
     | 
| 
       797 
820 
     | 
    
         
             
                }
         
     | 
| 
         @@ -822,7 +845,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou 
     | 
|
| 
       822 
845 
     | 
    
         
             
                    for (; str < end; str++) {
         
     | 
| 
       823 
846 
     | 
    
         
             
                        switch (cmap[(uint8_t)*str]) {
         
     | 
| 
       824 
847 
     | 
    
         
             
                        case '1':
         
     | 
| 
       825 
     | 
    
         
            -
                            if ( 
     | 
| 
      
 848 
     | 
    
         
            +
                            if (do_unicode_validation && check_start <= str) {
         
     | 
| 
       826 
849 
     | 
    
         
             
                                if (0 != (0x80 & (uint8_t)*str)) {
         
     | 
| 
       827 
850 
     | 
    
         
             
                                    if (0xC0 == (0xC0 & (uint8_t)*str)) {
         
     | 
| 
       828 
851 
     | 
    
         
             
                                        check_start = check_unicode(str, end, orig);
         
     | 
| 
         @@ -846,8 +869,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou 
     | 
|
| 
       846 
869 
     | 
    
         
             
                            }
         
     | 
| 
       847 
870 
     | 
    
         
             
                            break;
         
     | 
| 
       848 
871 
     | 
    
         
             
                        case '3':  // Unicode
         
     | 
| 
       849 
     | 
    
         
            -
                            if (0xe2 == (uint8_t)*str &&  
     | 
| 
       850 
     | 
    
         
            -
                                2 <= end - str) {
         
     | 
| 
      
 872 
     | 
    
         
            +
                            if (0xe2 == (uint8_t)*str && do_unicode_validation && 2 <= end - str) {
         
     | 
| 
       851 
873 
     | 
    
         
             
                                if (0x80 == (uint8_t)str[1] && (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
         
     | 
| 
       852 
874 
     | 
    
         
             
                                    str = dump_unicode(str, end, out, orig);
         
     | 
| 
       853 
875 
     | 
    
         
             
                                } else {
         
     | 
| 
         @@ -860,11 +882,13 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou 
     | 
|
| 
       860 
882 
     | 
    
         
             
                            break;
         
     | 
| 
       861 
883 
     | 
    
         
             
                        case '6':  // control characters
         
     | 
| 
       862 
884 
     | 
    
         
             
                            if (*(uint8_t *)str < 0x80) {
         
     | 
| 
      
 885 
     | 
    
         
            +
                                if (0 == (uint8_t)*str && out->opts->dump_opts.omit_null_byte) {
         
     | 
| 
      
 886 
     | 
    
         
            +
                                    break;
         
     | 
| 
      
 887 
     | 
    
         
            +
                                }
         
     | 
| 
       863 
888 
     | 
    
         
             
                                APPEND_CHARS(out->cur, "\\u00", 4);
         
     | 
| 
       864 
889 
     | 
    
         
             
                                dump_hex((uint8_t)*str, out);
         
     | 
| 
       865 
890 
     | 
    
         
             
                            } else {
         
     | 
| 
       866 
     | 
    
         
            -
                                if (0xe2 == (uint8_t)*str &&
         
     | 
| 
       867 
     | 
    
         
            -
                                    (JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 2 <= end - str) {
         
     | 
| 
      
 891 
     | 
    
         
            +
                                if (0xe2 == (uint8_t)*str && do_unicode_validation && 2 <= end - str) {
         
     | 
| 
       868 
892 
     | 
    
         
             
                                    if (0x80 == (uint8_t)str[1] && (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
         
     | 
| 
       869 
893 
     | 
    
         
             
                                        str = dump_unicode(str, end, out, orig);
         
     | 
| 
       870 
894 
     | 
    
         
             
                                    } else {
         
     | 
| 
         @@ -881,8 +905,7 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou 
     | 
|
| 
       881 
905 
     | 
    
         
             
                    }
         
     | 
| 
       882 
906 
     | 
    
         
             
                    *out->cur++ = '"';
         
     | 
| 
       883 
907 
     | 
    
         
             
                }
         
     | 
| 
       884 
     | 
    
         
            -
                if ( 
     | 
| 
       885 
     | 
    
         
            -
                    0 != (0x80 & *(str - 1))) {
         
     | 
| 
      
 908 
     | 
    
         
            +
                if (do_unicode_validation && 0 < str - orig && 0 != (0x80 & *(str - 1))) {
         
     | 
| 
       886 
909 
     | 
    
         
             
                    uint8_t c = (uint8_t) * (str - 1);
         
     | 
| 
       887 
910 
     | 
    
         
             
                    int     i;
         
     | 
| 
       888 
911 
     | 
    
         
             
                    int     scnt = (int)(str - orig);
         
     | 
| 
         @@ -932,7 +955,7 @@ void oj_dump_class(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       932 
955 
     | 
    
         
             
            }
         
     | 
| 
       933 
956 
     | 
    
         | 
| 
       934 
957 
     | 
    
         
             
            void oj_dump_obj_to_s(VALUE obj, Out out) {
         
     | 
| 
       935 
     | 
    
         
            -
                volatile VALUE rstr =  
     | 
| 
      
 958 
     | 
    
         
            +
                volatile VALUE rstr = oj_safe_string_convert(obj);
         
     | 
| 
       936 
959 
     | 
    
         | 
| 
       937 
960 
     | 
    
         
             
                oj_dump_cstr(RSTRING_PTR(rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
         
     | 
| 
       938 
961 
     | 
    
         
             
            }
         
     | 
| 
         @@ -944,15 +967,15 @@ void oj_dump_raw(const char *str, size_t cnt, Out out) { 
     | 
|
| 
       944 
967 
     | 
    
         
             
            }
         
     | 
| 
       945 
968 
     | 
    
         | 
| 
       946 
969 
     | 
    
         
             
            void oj_out_init(Out out) {
         
     | 
| 
       947 
     | 
    
         
            -
                out->buf 
     | 
| 
       948 
     | 
    
         
            -
                out->cur 
     | 
| 
       949 
     | 
    
         
            -
                out->end 
     | 
| 
      
 970 
     | 
    
         
            +
                out->buf       = out->stack_buffer;
         
     | 
| 
      
 971 
     | 
    
         
            +
                out->cur       = out->buf;
         
     | 
| 
      
 972 
     | 
    
         
            +
                out->end       = out->buf + sizeof(out->stack_buffer) - BUFFER_EXTRA;
         
     | 
| 
       950 
973 
     | 
    
         
             
                out->allocated = false;
         
     | 
| 
       951 
974 
     | 
    
         
             
            }
         
     | 
| 
       952 
975 
     | 
    
         | 
| 
       953 
976 
     | 
    
         
             
            void oj_out_free(Out out) {
         
     | 
| 
       954 
977 
     | 
    
         
             
                if (out->allocated) {
         
     | 
| 
       955 
     | 
    
         
            -
                     
     | 
| 
      
 978 
     | 
    
         
            +
                    OJ_R_FREE(out->buf);  // TBD
         
     | 
| 
       956 
979 
     | 
    
         
             
                }
         
     | 
| 
       957 
980 
     | 
    
         
             
            }
         
     | 
| 
       958 
981 
     | 
    
         | 
| 
         @@ -966,9 +989,9 @@ void oj_grow_out(Out out, size_t len) { 
     | 
|
| 
       966 
989 
     | 
    
         
             
                    size += len;
         
     | 
| 
       967 
990 
     | 
    
         
             
                }
         
     | 
| 
       968 
991 
     | 
    
         
             
                if (out->allocated) {
         
     | 
| 
       969 
     | 
    
         
            -
                     
     | 
| 
      
 992 
     | 
    
         
            +
                    OJ_R_REALLOC_N(buf, char, (size + BUFFER_EXTRA));
         
     | 
| 
       970 
993 
     | 
    
         
             
                } else {
         
     | 
| 
       971 
     | 
    
         
            -
                    buf            =  
     | 
| 
      
 994 
     | 
    
         
            +
                    buf            = OJ_R_ALLOC_N(char, (size + BUFFER_EXTRA));
         
     | 
| 
       972 
995 
     | 
    
         
             
                    out->allocated = true;
         
     | 
| 
       973 
996 
     | 
    
         
             
                    memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
         
     | 
| 
       974 
997 
     | 
    
         
             
                }
         
     | 
| 
         @@ -983,26 +1006,60 @@ void oj_grow_out(Out out, size_t len) { 
     | 
|
| 
       983 
1006 
     | 
    
         
             
            void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       984 
1007 
     | 
    
         
             
                assure_size(out, 4);
         
     | 
| 
       985 
1008 
     | 
    
         
             
                APPEND_CHARS(out->cur, "null", 4);
         
     | 
| 
       986 
     | 
    
         
            -
                *out->cur 
     | 
| 
      
 1009 
     | 
    
         
            +
                *out->cur = '\0';
         
     | 
| 
       987 
1010 
     | 
    
         
             
            }
         
     | 
| 
       988 
1011 
     | 
    
         | 
| 
       989 
1012 
     | 
    
         
             
            void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       990 
1013 
     | 
    
         
             
                assure_size(out, 4);
         
     | 
| 
       991 
1014 
     | 
    
         
             
                APPEND_CHARS(out->cur, "true", 4);
         
     | 
| 
       992 
     | 
    
         
            -
                *out->cur 
     | 
| 
      
 1015 
     | 
    
         
            +
                *out->cur = '\0';
         
     | 
| 
       993 
1016 
     | 
    
         
             
            }
         
     | 
| 
       994 
1017 
     | 
    
         | 
| 
       995 
1018 
     | 
    
         
             
            void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       996 
1019 
     | 
    
         
             
                assure_size(out, 5);
         
     | 
| 
       997 
1020 
     | 
    
         
             
                APPEND_CHARS(out->cur, "false", 5);
         
     | 
| 
       998 
     | 
    
         
            -
                *out->cur 
     | 
| 
      
 1021 
     | 
    
         
            +
                *out->cur = '\0';
         
     | 
| 
      
 1022 
     | 
    
         
            +
            }
         
     | 
| 
      
 1023 
     | 
    
         
            +
             
     | 
| 
      
 1024 
     | 
    
         
            +
            static const char digits_table[] = "\
         
     | 
| 
      
 1025 
     | 
    
         
            +
            00010203040506070809\
         
     | 
| 
      
 1026 
     | 
    
         
            +
            10111213141516171819\
         
     | 
| 
      
 1027 
     | 
    
         
            +
            20212223242526272829\
         
     | 
| 
      
 1028 
     | 
    
         
            +
            30313233343536373839\
         
     | 
| 
      
 1029 
     | 
    
         
            +
            40414243444546474849\
         
     | 
| 
      
 1030 
     | 
    
         
            +
            50515253545556575859\
         
     | 
| 
      
 1031 
     | 
    
         
            +
            60616263646566676869\
         
     | 
| 
      
 1032 
     | 
    
         
            +
            70717273747576777879\
         
     | 
| 
      
 1033 
     | 
    
         
            +
            80818283848586878889\
         
     | 
| 
      
 1034 
     | 
    
         
            +
            90919293949596979899";
         
     | 
| 
      
 1035 
     | 
    
         
            +
             
     | 
| 
      
 1036 
     | 
    
         
            +
            char *oj_longlong_to_string(long long num, bool negative, char *buf) {
         
     | 
| 
      
 1037 
     | 
    
         
            +
                while (100 <= num) {
         
     | 
| 
      
 1038 
     | 
    
         
            +
                    unsigned idx = num % 100 * 2;
         
     | 
| 
      
 1039 
     | 
    
         
            +
                    *buf--       = digits_table[idx + 1];
         
     | 
| 
      
 1040 
     | 
    
         
            +
                    *buf--       = digits_table[idx];
         
     | 
| 
      
 1041 
     | 
    
         
            +
                    num /= 100;
         
     | 
| 
      
 1042 
     | 
    
         
            +
                }
         
     | 
| 
      
 1043 
     | 
    
         
            +
                if (num < 10) {
         
     | 
| 
      
 1044 
     | 
    
         
            +
                    *buf-- = num + '0';
         
     | 
| 
      
 1045 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1046 
     | 
    
         
            +
                    *buf-- = digits_table[num * 2 + 1];
         
     | 
| 
      
 1047 
     | 
    
         
            +
                    *buf-- = digits_table[num * 2];
         
     | 
| 
      
 1048 
     | 
    
         
            +
                }
         
     | 
| 
      
 1049 
     | 
    
         
            +
             
     | 
| 
      
 1050 
     | 
    
         
            +
                if (negative) {
         
     | 
| 
      
 1051 
     | 
    
         
            +
                    *buf = '-';
         
     | 
| 
      
 1052 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 1053 
     | 
    
         
            +
                    buf++;
         
     | 
| 
      
 1054 
     | 
    
         
            +
                }
         
     | 
| 
      
 1055 
     | 
    
         
            +
                return buf;
         
     | 
| 
       999 
1056 
     | 
    
         
             
            }
         
     | 
| 
       1000 
1057 
     | 
    
         | 
| 
       1001 
1058 
     | 
    
         
             
            void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
         
     | 
| 
       1002 
1059 
     | 
    
         
             
                char      buf[32];
         
     | 
| 
       1003 
     | 
    
         
            -
                char 
     | 
| 
      
 1060 
     | 
    
         
            +
                char     *b              = buf + sizeof(buf) - 1;
         
     | 
| 
       1004 
1061 
     | 
    
         
             
                long long num            = NUM2LL(obj);
         
     | 
| 
       1005 
     | 
    
         
            -
                 
     | 
| 
      
 1062 
     | 
    
         
            +
                bool      neg            = false;
         
     | 
| 
       1006 
1063 
     | 
    
         
             
                size_t    cnt            = 0;
         
     | 
| 
       1007 
1064 
     | 
    
         
             
                bool      dump_as_string = false;
         
     | 
| 
       1008 
1065 
     | 
    
         | 
| 
         @@ -1011,7 +1068,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1011 
1068 
     | 
    
         
             
                    dump_as_string = true;
         
     | 
| 
       1012 
1069 
     | 
    
         
             
                }
         
     | 
| 
       1013 
1070 
     | 
    
         
             
                if (0 > num) {
         
     | 
| 
       1014 
     | 
    
         
            -
                    neg =  
     | 
| 
      
 1071 
     | 
    
         
            +
                    neg = true;
         
     | 
| 
       1015 
1072 
     | 
    
         
             
                    num = -num;
         
     | 
| 
       1016 
1073 
     | 
    
         
             
                }
         
     | 
| 
       1017 
1074 
     | 
    
         
             
                *b-- = '\0';
         
     | 
| 
         @@ -1020,14 +1077,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1020 
1077 
     | 
    
         
             
                    *b-- = '"';
         
     | 
| 
       1021 
1078 
     | 
    
         
             
                }
         
     | 
| 
       1022 
1079 
     | 
    
         
             
                if (0 < num) {
         
     | 
| 
       1023 
     | 
    
         
            -
                     
     | 
| 
       1024 
     | 
    
         
            -
                        *b = (num % 10) + '0';
         
     | 
| 
       1025 
     | 
    
         
            -
                    }
         
     | 
| 
       1026 
     | 
    
         
            -
                    if (neg) {
         
     | 
| 
       1027 
     | 
    
         
            -
                        *b = '-';
         
     | 
| 
       1028 
     | 
    
         
            -
                    } else {
         
     | 
| 
       1029 
     | 
    
         
            -
                        b++;
         
     | 
| 
       1030 
     | 
    
         
            -
                    }
         
     | 
| 
      
 1080 
     | 
    
         
            +
                    b = oj_longlong_to_string(num, neg, b);
         
     | 
| 
       1031 
1081 
     | 
    
         
             
                } else {
         
     | 
| 
       1032 
1082 
     | 
    
         
             
                    *b = '0';
         
     | 
| 
       1033 
1083 
     | 
    
         
             
                }
         
     | 
| 
         @@ -1173,7 +1223,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) { 
     | 
|
| 
       1173 
1223 
     | 
    
         
             
                } else if (d == (double)(long long int)d) {
         
     | 
| 
       1174 
1224 
     | 
    
         
             
                    cnt = snprintf(buf, sizeof(buf), "%.1f", d);
         
     | 
| 
       1175 
1225 
     | 
    
         
             
                } else if (0 == out->opts->float_prec) {
         
     | 
| 
       1176 
     | 
    
         
            -
                    volatile VALUE rstr =  
     | 
| 
      
 1226 
     | 
    
         
            +
                    volatile VALUE rstr = oj_safe_string_convert(obj);
         
     | 
| 
       1177 
1227 
     | 
    
         | 
| 
       1178 
1228 
     | 
    
         
             
                    cnt = (int)RSTRING_LEN(rstr);
         
     | 
| 
       1179 
1229 
     | 
    
         
             
                    if ((int)sizeof(buf) <= cnt) {
         
     | 
| 
         @@ -1195,7 +1245,7 @@ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char 
     | 
|
| 
       1195 
1245 
     | 
    
         
             
                // Round off issues at 16 significant digits so check for obvious ones of
         
     | 
| 
       1196 
1246 
     | 
    
         
             
                // 0001 and 9999.
         
     | 
| 
       1197 
1247 
     | 
    
         
             
                if (17 <= cnt && (0 == strcmp("0001", buf + cnt - 4) || 0 == strcmp("9999", buf + cnt - 4))) {
         
     | 
| 
       1198 
     | 
    
         
            -
                    volatile VALUE rstr =  
     | 
| 
      
 1248 
     | 
    
         
            +
                    volatile VALUE rstr = oj_safe_string_convert(obj);
         
     | 
| 
       1199 
1249 
     | 
    
         | 
| 
       1200 
1250 
     | 
    
         
             
                    strcpy(buf, RSTRING_PTR(rstr));
         
     | 
| 
       1201 
1251 
     | 
    
         
             
                    cnt = (int)RSTRING_LEN(rstr);
         
     | 
    
        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 
     | 
    
         
            -
                     
     | 
| 
       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 
     | 
    
         
             
                }
         
     |