oj 3.13.17 → 3.13.20
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 +12 -0
- data/ext/oj/custom.c +7 -7
- data/ext/oj/dump.c +2 -2
- data/ext/oj/dump_compat.c +5 -5
- data/ext/oj/dump_object.c +3 -3
- data/ext/oj/dump_strict.c +5 -5
- data/ext/oj/extconf.rb +1 -1
- data/ext/oj/oj.c +1 -0
- data/ext/oj/parse.c +57 -66
- data/ext/oj/parse.h +2 -0
- data/ext/oj/rails.c +5 -5
- data/ext/oj/saj2.c +3 -3
- data/ext/oj/wab.c +2 -2
- data/lib/oj/version.rb +1 -1
- data/test/helper.rb +8 -2
- data/test/json_gem/json_parser_test.rb +2 -0
- data/test/json_gem/test_helper.rb +7 -3
- data/test/test_custom.rb +12 -0
- data/test/test_file.rb +7 -2
- data/test/test_gc.rb +13 -0
- data/test/test_integer_range.rb +6 -0
- data/test/test_object.rb +39 -1
- data/test/test_parser_saj.rb +11 -0
- data/test/test_scp.rb +4 -4
- data/test/test_strict.rb +2 -0
- data/test/test_wab.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 958a558e09c25d5de9548af67dff6586686def4a9073b3cee6ba8403930eda48
|
4
|
+
data.tar.gz: 2f928e9e849ca695d03ad9a396ec7f2df3508b99d10baa11a8cb538a7b3a0e52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 758bb300ed853d161750d100a8fbdd755e37ae8e15ae94f1e7a4cbd613c787002758d4fc5834fd47a7ef8fb78446208f896afee31c0bc023bcdeb381aba1f98c
|
7
|
+
data.tar.gz: 54127873544ca146a61d7ca4012ff9d2eb4b83bdcbb3f06eea092d4e4ad517c453196a59edc2743b42736ab276e0eb96889045e0d3f2200dcbaf4a2b79353db3
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.13.20 - 2022-08-07
|
4
|
+
|
5
|
+
- SSE4 made optional with a `--with-sse42` flag to the compile.
|
6
|
+
|
7
|
+
## 3.13.19 - 2022-07-29
|
8
|
+
|
9
|
+
- TruffleRuby issues resolved.
|
10
|
+
|
11
|
+
## 3.13.18 - 2022-07-25
|
12
|
+
|
13
|
+
- Fixed SSE detection at run time.
|
14
|
+
|
3
15
|
## 3.13.17 - 2022-07-15
|
4
16
|
|
5
17
|
- Fixed Oj::Parser to detect unterminated arrays and objects.
|
data/ext/oj/custom.c
CHANGED
@@ -484,7 +484,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
484
484
|
const char * s;
|
485
485
|
int len;
|
486
486
|
|
487
|
-
if (Yes == out->opts->trace) {
|
487
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
488
488
|
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
489
489
|
}
|
490
490
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
@@ -492,7 +492,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
492
492
|
} else {
|
493
493
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
494
494
|
}
|
495
|
-
if (Yes == out->opts->trace) {
|
495
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
496
496
|
oj_trace("to_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
497
497
|
}
|
498
498
|
s = RSTRING_PTR(rs);
|
@@ -504,7 +504,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
504
504
|
} else if (Yes == out->opts->as_json && rb_respond_to(obj, oj_as_json_id)) {
|
505
505
|
volatile VALUE aj;
|
506
506
|
|
507
|
-
if (Yes == out->opts->trace) {
|
507
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
508
508
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
509
509
|
}
|
510
510
|
// Some classes elect to not take an options argument so check the arity
|
@@ -514,7 +514,7 @@ static VALUE dump_common(VALUE obj, int depth, Out out) {
|
|
514
514
|
} else {
|
515
515
|
aj = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
516
516
|
}
|
517
|
-
if (Yes == out->opts->trace) {
|
517
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
518
518
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
519
519
|
}
|
520
520
|
// Catch the obvious brain damaged recursive dumping.
|
@@ -885,7 +885,7 @@ static DumpFunc custom_funcs[] = {
|
|
885
885
|
void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
886
886
|
int type = rb_type(obj);
|
887
887
|
|
888
|
-
if (Yes == out->opts->trace) {
|
888
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
889
889
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
890
890
|
}
|
891
891
|
if (MAX_DEPTH < depth) {
|
@@ -896,14 +896,14 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
896
896
|
|
897
897
|
if (NULL != f) {
|
898
898
|
f(obj, depth, out, true);
|
899
|
-
if (Yes == out->opts->trace) {
|
899
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
900
900
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
901
901
|
}
|
902
902
|
return;
|
903
903
|
}
|
904
904
|
}
|
905
905
|
oj_dump_nil(Qnil, depth, out, false);
|
906
|
-
if (Yes == out->opts->trace) {
|
906
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
907
907
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
908
908
|
}
|
909
909
|
}
|
data/ext/oj/dump.c
CHANGED
@@ -736,11 +736,11 @@ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
|
|
736
736
|
} else {
|
737
737
|
volatile VALUE jv;
|
738
738
|
|
739
|
-
if (Yes == out->opts->trace) {
|
739
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
740
740
|
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
741
741
|
}
|
742
742
|
jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
|
743
|
-
if (Yes == out->opts->trace) {
|
743
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
744
744
|
oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
745
745
|
}
|
746
746
|
oj_dump_raw(RSTRING_PTR(jv), (size_t)RSTRING_LEN(jv), out);
|
data/ext/oj/dump_compat.c
CHANGED
@@ -109,7 +109,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
109
109
|
const char *s;
|
110
110
|
int len;
|
111
111
|
|
112
|
-
if (Yes == out->opts->trace) {
|
112
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
113
113
|
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyIn);
|
114
114
|
}
|
115
115
|
if (0 == rb_obj_method_arity(obj, oj_to_json_id)) {
|
@@ -117,7 +117,7 @@ dump_to_json(VALUE obj, Out out) {
|
|
117
117
|
} else {
|
118
118
|
rs = rb_funcall2(obj, oj_to_json_id, out->argc, out->argv);
|
119
119
|
}
|
120
|
-
if (Yes == out->opts->trace) {
|
120
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
121
121
|
oj_trace("to_json", obj, __FILE__, __LINE__, 0, TraceRubyOut);
|
122
122
|
}
|
123
123
|
|
@@ -893,7 +893,7 @@ void
|
|
893
893
|
oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
894
894
|
int type = rb_type(obj);
|
895
895
|
|
896
|
-
if (Yes == out->opts->trace) {
|
896
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
897
897
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
898
898
|
}
|
899
899
|
if (out->opts->dump_opts.max_depth <= depth) {
|
@@ -918,14 +918,14 @@ oj_dump_compat_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
918
918
|
|
919
919
|
if (NULL != f) {
|
920
920
|
f(obj, depth, out, as_ok);
|
921
|
-
if (Yes == out->opts->trace) {
|
921
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
922
922
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
923
923
|
}
|
924
924
|
return;
|
925
925
|
}
|
926
926
|
}
|
927
927
|
oj_dump_nil(Qnil, depth, out, false);
|
928
|
-
if (Yes == out->opts->trace) {
|
928
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
929
929
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
930
930
|
}
|
931
931
|
}
|
data/ext/oj/dump_object.c
CHANGED
@@ -682,7 +682,7 @@ static DumpFunc obj_funcs[] = {
|
|
682
682
|
void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
683
683
|
int type = rb_type(obj);
|
684
684
|
|
685
|
-
if (Yes == out->opts->trace) {
|
685
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
686
686
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
687
687
|
}
|
688
688
|
if (MAX_DEPTH < depth) {
|
@@ -693,14 +693,14 @@ void oj_dump_obj_val(VALUE obj, int depth, Out out) {
|
|
693
693
|
|
694
694
|
if (NULL != f) {
|
695
695
|
f(obj, depth, out, false);
|
696
|
-
if (Yes == out->opts->trace) {
|
696
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
697
697
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
698
698
|
}
|
699
699
|
return;
|
700
700
|
}
|
701
701
|
}
|
702
702
|
oj_dump_nil(Qnil, depth, out, false);
|
703
|
-
if (Yes == out->opts->trace) {
|
703
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
704
704
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
705
705
|
}
|
706
706
|
}
|
data/ext/oj/dump_strict.c
CHANGED
@@ -338,7 +338,7 @@ static DumpFunc strict_funcs[] = {
|
|
338
338
|
void oj_dump_strict_val(VALUE obj, int depth, Out out) {
|
339
339
|
int type = rb_type(obj);
|
340
340
|
|
341
|
-
if (Yes == out->opts->trace) {
|
341
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
342
342
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
343
343
|
}
|
344
344
|
if (MAX_DEPTH < depth) {
|
@@ -349,7 +349,7 @@ void oj_dump_strict_val(VALUE obj, int depth, Out out) {
|
|
349
349
|
|
350
350
|
if (NULL != f) {
|
351
351
|
f(obj, depth, out, false);
|
352
|
-
if (Yes == out->opts->trace) {
|
352
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
353
353
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
354
354
|
}
|
355
355
|
return;
|
@@ -386,7 +386,7 @@ static DumpFunc null_funcs[] = {
|
|
386
386
|
void oj_dump_null_val(VALUE obj, int depth, Out out) {
|
387
387
|
int type = rb_type(obj);
|
388
388
|
|
389
|
-
if (Yes == out->opts->trace) {
|
389
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
390
390
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
391
391
|
}
|
392
392
|
if (MAX_DEPTH < depth) {
|
@@ -397,14 +397,14 @@ void oj_dump_null_val(VALUE obj, int depth, Out out) {
|
|
397
397
|
|
398
398
|
if (NULL != f) {
|
399
399
|
f(obj, depth, out, false);
|
400
|
-
if (Yes == out->opts->trace) {
|
400
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
401
401
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
402
402
|
}
|
403
403
|
return;
|
404
404
|
}
|
405
405
|
}
|
406
406
|
oj_dump_nil(Qnil, depth, out, false);
|
407
|
-
if (Yes == out->opts->trace) {
|
407
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
408
408
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
409
409
|
}
|
410
410
|
}
|
data/ext/oj/extconf.rb
CHANGED
@@ -34,7 +34,7 @@ have_func('rb_hash_bulk_insert', 'ruby.h') unless '2' == version[0] && '6' == ve
|
|
34
34
|
|
35
35
|
dflags['OJ_DEBUG'] = true unless ENV['OJ_DEBUG'].nil?
|
36
36
|
|
37
|
-
if
|
37
|
+
if with_config('--with-sse42')
|
38
38
|
$CPPFLAGS += ' -msse4.2'
|
39
39
|
dflags['OJ_USE_SSE4_2'] = 1
|
40
40
|
end
|
data/ext/oj/oj.c
CHANGED
data/ext/oj/parse.c
CHANGED
@@ -192,9 +192,7 @@ static inline const char *scan_string_noSIMD(const char *str, const char *end) {
|
|
192
192
|
return str;
|
193
193
|
}
|
194
194
|
|
195
|
-
#
|
196
|
-
#include <nmmintrin.h>
|
197
|
-
|
195
|
+
#ifdef OJ_USE_SSE4_2
|
198
196
|
static inline const char *scan_string_SIMD(const char *str, const char *end) {
|
199
197
|
static const char chars[16] = "\x00\\\"";
|
200
198
|
const __m128i terminate = _mm_loadu_si128((const __m128i *)&chars[0]);
|
@@ -213,6 +211,14 @@ static inline const char *scan_string_SIMD(const char *str, const char *end) {
|
|
213
211
|
}
|
214
212
|
#endif
|
215
213
|
|
214
|
+
static const char *(*scan_func) (const char *str, const char *end) = scan_string_noSIMD;
|
215
|
+
|
216
|
+
void oj_scanner_init(void) {
|
217
|
+
#ifdef OJ_USE_SSE4_2
|
218
|
+
scan_func = scan_string_SIMD;
|
219
|
+
#endif
|
220
|
+
}
|
221
|
+
|
216
222
|
// entered at /
|
217
223
|
static void read_escaped_str(ParseInfo pi, const char *start) {
|
218
224
|
struct _buf buf;
|
@@ -225,11 +231,7 @@ static void read_escaped_str(ParseInfo pi, const char *start) {
|
|
225
231
|
buf_append_string(&buf, start, cnt);
|
226
232
|
|
227
233
|
for (s = pi->cur; '"' != *s;) {
|
228
|
-
|
229
|
-
const char *scanned = scan_string_SIMD(s, pi->end);
|
230
|
-
#else
|
231
|
-
const char *scanned = scan_string_noSIMD(s, pi->end);
|
232
|
-
#endif
|
234
|
+
const char *scanned = scan_func(s, pi->end);
|
233
235
|
if (scanned >= pi->end) {
|
234
236
|
oj_set_error_at(pi,
|
235
237
|
oj_parse_error_class,
|
@@ -369,11 +371,7 @@ static void read_str(ParseInfo pi) {
|
|
369
371
|
const char *str = pi->cur;
|
370
372
|
Val parent = stack_peek(&pi->stack);
|
371
373
|
|
372
|
-
|
373
|
-
pi->cur = scan_string_SIMD(pi->cur, pi->end);
|
374
|
-
#else
|
375
|
-
pi->cur = scan_string_noSIMD(pi->cur, pi->end);
|
376
|
-
#endif
|
374
|
+
pi->cur = scan_func(pi->cur, pi->end);
|
377
375
|
if (RB_UNLIKELY(pi->end <= pi->cur)) {
|
378
376
|
oj_set_error_at(pi,
|
379
377
|
oj_parse_error_class,
|
@@ -503,33 +501,31 @@ static void read_num(ParseInfo pi) {
|
|
503
501
|
int dec_cnt = 0;
|
504
502
|
bool zero1 = false;
|
505
503
|
|
504
|
+
// Skip leading zeros.
|
505
|
+
for (; '0' == *pi->cur; pi->cur++) {
|
506
|
+
zero1 = true;
|
507
|
+
}
|
508
|
+
|
506
509
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
507
|
-
|
508
|
-
zero1 = true;
|
509
|
-
}
|
510
|
-
if (0 < ni.i) {
|
511
|
-
dec_cnt++;
|
512
|
-
}
|
513
|
-
if (!ni.big) {
|
514
|
-
int d = (*pi->cur - '0');
|
510
|
+
int d = (*pi->cur - '0');
|
515
511
|
|
516
|
-
|
517
|
-
|
518
|
-
oj_set_error_at(pi,
|
519
|
-
oj_parse_error_class,
|
520
|
-
__FILE__,
|
521
|
-
__LINE__,
|
522
|
-
"not a number");
|
523
|
-
return;
|
524
|
-
}
|
525
|
-
zero1 = false;
|
526
|
-
}
|
527
|
-
ni.i = ni.i * 10 + d;
|
528
|
-
if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
|
529
|
-
ni.big = 1;
|
530
|
-
}
|
512
|
+
if (RB_LIKELY(0 != ni.i)) {
|
513
|
+
dec_cnt++;
|
531
514
|
}
|
515
|
+
ni.i = ni.i * 10 + d;
|
516
|
+
}
|
517
|
+
if (RB_UNLIKELY(0 != ni.i && zero1 && CompatMode == pi->options.mode)) {
|
518
|
+
oj_set_error_at(pi,
|
519
|
+
oj_parse_error_class,
|
520
|
+
__FILE__,
|
521
|
+
__LINE__,
|
522
|
+
"not a number");
|
523
|
+
return;
|
524
|
+
}
|
525
|
+
if (INT64_MAX <= ni.i || DEC_MAX < dec_cnt) {
|
526
|
+
ni.big = true;
|
532
527
|
}
|
528
|
+
|
533
529
|
if ('.' == *pi->cur) {
|
534
530
|
pi->cur++;
|
535
531
|
// A trailing . is not a valid decimal but if encountered allow it
|
@@ -549,25 +545,20 @@ static void read_num(ParseInfo pi) {
|
|
549
545
|
for (; '0' <= *pi->cur && *pi->cur <= '9'; pi->cur++) {
|
550
546
|
int d = (*pi->cur - '0');
|
551
547
|
|
552
|
-
if (0
|
548
|
+
if (RB_LIKELY(0 != ni.num || 0 != ni.i)) {
|
553
549
|
dec_cnt++;
|
554
550
|
}
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
564
|
-
if (!ni.no_big) {
|
565
|
-
ni.big = true;
|
566
|
-
}
|
567
|
-
}
|
568
|
-
}
|
551
|
+
ni.num = ni.num * 10 + d;
|
552
|
+
ni.div *= 10;
|
553
|
+
ni.di++;
|
554
|
+
}
|
555
|
+
}
|
556
|
+
if (INT64_MAX <= ni.div || DEC_MAX < dec_cnt) {
|
557
|
+
if (!ni.no_big) {
|
558
|
+
ni.big = true;
|
569
559
|
}
|
570
560
|
}
|
561
|
+
|
571
562
|
if ('e' == *pi->cur || 'E' == *pi->cur) {
|
572
563
|
int eneg = 0;
|
573
564
|
|
@@ -640,7 +631,7 @@ static void read_num(ParseInfo pi) {
|
|
640
631
|
}
|
641
632
|
|
642
633
|
static void array_start(ParseInfo pi) {
|
643
|
-
|
634
|
+
VALUE v = pi->start_array(pi);
|
644
635
|
|
645
636
|
stack_push(&pi->stack, v, NEXT_ARRAY_NEW);
|
646
637
|
}
|
@@ -664,13 +655,13 @@ static void array_end(ParseInfo pi) {
|
|
664
655
|
}
|
665
656
|
|
666
657
|
static void hash_start(ParseInfo pi) {
|
667
|
-
|
658
|
+
VALUE v = pi->start_hash(pi);
|
668
659
|
|
669
660
|
stack_push(&pi->stack, v, NEXT_HASH_NEW);
|
670
661
|
}
|
671
662
|
|
672
663
|
static void hash_end(ParseInfo pi) {
|
673
|
-
|
664
|
+
Val hash = stack_peek(&pi->stack);
|
674
665
|
|
675
666
|
// leave hash on stack until just before
|
676
667
|
if (0 == hash) {
|
@@ -857,7 +848,7 @@ static long double exp_plus[] = {
|
|
857
848
|
|
858
849
|
VALUE
|
859
850
|
oj_num_as_value(NumInfo ni) {
|
860
|
-
|
851
|
+
VALUE rnum = Qnil;
|
861
852
|
|
862
853
|
if (ni->infinity) {
|
863
854
|
if (ni->neg) {
|
@@ -892,7 +883,7 @@ oj_num_as_value(NumInfo ni) {
|
|
892
883
|
}
|
893
884
|
} else { // decimal
|
894
885
|
if (ni->big) {
|
895
|
-
|
886
|
+
VALUE bd = rb_str_new(ni->str, ni->len);
|
896
887
|
|
897
888
|
rnum = rb_rescue2(parse_big_decimal, bd, rescue_big_decimal, bd, rb_eException, 0);
|
898
889
|
if (ni->no_big) {
|
@@ -920,7 +911,7 @@ oj_num_as_value(NumInfo ni) {
|
|
920
911
|
}
|
921
912
|
rnum = rb_float_new((double)ld);
|
922
913
|
} else if (RubyDec == ni->bigdec_load) {
|
923
|
-
|
914
|
+
VALUE sv = rb_str_new(ni->str, ni->len);
|
924
915
|
|
925
916
|
rnum = rb_funcall(sv, rb_intern("to_f"), 0);
|
926
917
|
} else {
|
@@ -1015,7 +1006,7 @@ static VALUE protect_parse(VALUE pip) {
|
|
1015
1006
|
|
1016
1007
|
extern int oj_utf8_index;
|
1017
1008
|
|
1018
|
-
static void oj_pi_set_input_str(ParseInfo pi,
|
1009
|
+
static void oj_pi_set_input_str(ParseInfo pi, VALUE *inputp) {
|
1019
1010
|
int idx = RB_ENCODING_GET(*inputp);
|
1020
1011
|
|
1021
1012
|
if (oj_utf8_encoding_index != idx) {
|
@@ -1028,12 +1019,12 @@ static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) {
|
|
1028
1019
|
|
1029
1020
|
VALUE
|
1030
1021
|
oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yieldOk) {
|
1031
|
-
char *
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
int
|
1036
|
-
int
|
1022
|
+
char * buf = 0;
|
1023
|
+
VALUE input;
|
1024
|
+
VALUE wrapped_stack;
|
1025
|
+
VALUE result = Qnil;
|
1026
|
+
int line = 0;
|
1027
|
+
int free_json = 0;
|
1037
1028
|
|
1038
1029
|
if (argc < 1) {
|
1039
1030
|
rb_raise(rb_eArgError, "Wrong number of arguments to parse.");
|
@@ -1069,8 +1060,8 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
1069
1060
|
rb_raise(rb_eTypeError, "Nil is not a valid JSON source.");
|
1070
1061
|
}
|
1071
1062
|
} else {
|
1072
|
-
VALUE
|
1073
|
-
|
1063
|
+
VALUE clas = rb_obj_class(input);
|
1064
|
+
VALUE s;
|
1074
1065
|
|
1075
1066
|
if (oj_stringio_class == clas) {
|
1076
1067
|
s = rb_funcall2(input, oj_string_id, 0, 0);
|
data/ext/oj/parse.h
CHANGED
data/ext/oj/rails.c
CHANGED
@@ -517,7 +517,7 @@ static void dump_as_string(VALUE obj, int depth, Out out, bool as_ok) {
|
|
517
517
|
static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
518
518
|
volatile VALUE ja;
|
519
519
|
|
520
|
-
if (Yes == out->opts->trace) {
|
520
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
521
521
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
|
522
522
|
}
|
523
523
|
// Some classes elect to not take an options argument so check the arity
|
@@ -527,7 +527,7 @@ static void dump_as_json(VALUE obj, int depth, Out out, bool as_ok) {
|
|
527
527
|
} else {
|
528
528
|
ja = rb_funcall2(obj, oj_as_json_id, out->argc, out->argv);
|
529
529
|
}
|
530
|
-
if (Yes == out->opts->trace) {
|
530
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
531
531
|
oj_trace("as_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
|
532
532
|
}
|
533
533
|
|
@@ -1464,7 +1464,7 @@ static DumpFunc rails_funcs[] = {
|
|
1464
1464
|
static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
1465
1465
|
int type = rb_type(obj);
|
1466
1466
|
|
1467
|
-
if (Yes == out->opts->trace) {
|
1467
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1468
1468
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
1469
1469
|
}
|
1470
1470
|
if (MAX_DEPTH < depth) {
|
@@ -1475,14 +1475,14 @@ static void dump_rails_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1475
1475
|
|
1476
1476
|
if (NULL != f) {
|
1477
1477
|
f(obj, depth, out, as_ok);
|
1478
|
-
if (Yes == out->opts->trace) {
|
1478
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1479
1479
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
1480
1480
|
}
|
1481
1481
|
return;
|
1482
1482
|
}
|
1483
1483
|
}
|
1484
1484
|
oj_dump_nil(Qnil, depth, out, false);
|
1485
|
-
if (Yes == out->opts->trace) {
|
1485
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
1486
1486
|
oj_trace("dump", Qnil, __FILE__, __LINE__, depth, TraceOut);
|
1487
1487
|
}
|
1488
1488
|
}
|
data/ext/oj/saj2.c
CHANGED
@@ -289,7 +289,7 @@ static void add_float_key_loc(ojParser p) {
|
|
289
289
|
}
|
290
290
|
|
291
291
|
static void add_big(ojParser p) {
|
292
|
-
rb_funcall((
|
292
|
+
rb_funcall(((Delegate)p->ctx)->handler,
|
293
293
|
oj_add_value_id,
|
294
294
|
2,
|
295
295
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
@@ -297,7 +297,7 @@ static void add_big(ojParser p) {
|
|
297
297
|
}
|
298
298
|
|
299
299
|
static void add_big_loc(ojParser p) {
|
300
|
-
rb_funcall((
|
300
|
+
rb_funcall(((Delegate)p->ctx)->handler,
|
301
301
|
oj_add_value_id,
|
302
302
|
4,
|
303
303
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
@@ -307,7 +307,7 @@ static void add_big_loc(ojParser p) {
|
|
307
307
|
}
|
308
308
|
|
309
309
|
static void add_big_key(ojParser p) {
|
310
|
-
rb_funcall((
|
310
|
+
rb_funcall(((Delegate)p->ctx)->handler,
|
311
311
|
oj_add_value_id,
|
312
312
|
2,
|
313
313
|
rb_funcall(rb_cObject, oj_bigdecimal_id, 1, rb_str_new(buf_str(&p->buf), buf_len(&p->buf))),
|
data/ext/oj/wab.c
CHANGED
@@ -266,7 +266,7 @@ static DumpFunc wab_funcs[] = {
|
|
266
266
|
void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
267
267
|
int type = rb_type(obj);
|
268
268
|
|
269
|
-
if (Yes == out->opts->trace) {
|
269
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
270
270
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceIn);
|
271
271
|
}
|
272
272
|
if (MAX_DEPTH < depth) {
|
@@ -277,7 +277,7 @@ void oj_dump_wab_val(VALUE obj, int depth, Out out) {
|
|
277
277
|
|
278
278
|
if (NULL != f) {
|
279
279
|
f(obj, depth, out, false);
|
280
|
-
if (Yes == out->opts->trace) {
|
280
|
+
if (RB_UNLIKELY(Yes == out->opts->trace)) {
|
281
281
|
oj_trace("dump", obj, __FILE__, __LINE__, depth, TraceOut);
|
282
282
|
}
|
283
283
|
return;
|
data/lib/oj/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -19,10 +19,16 @@ require 'pp'
|
|
19
19
|
require 'oj'
|
20
20
|
|
21
21
|
|
22
|
-
|
22
|
+
def verify_gc_compaction
|
23
23
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
24
24
|
# move objects around, helping to find object movement bugs.
|
25
|
-
GC.verify_compaction_references(
|
25
|
+
if defined?(GC.verify_compaction_references) == 'method' && !(RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/)
|
26
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2.0")
|
27
|
+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
|
28
|
+
else
|
29
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
30
|
+
end
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
|
@@ -24,6 +24,8 @@ class JSONParserTest < Test::Unit::TestCase
|
|
24
24
|
end if defined?(Encoding::UTF_16)
|
25
25
|
|
26
26
|
def test_error_message_encoding
|
27
|
+
omit 'TruffleRuby causes NameError(<uninitialized constant JSON::Ext>)' if RUBY_ENGINE == 'truffleruby'
|
28
|
+
|
27
29
|
bug10705 = '[ruby-core:67386] [Bug #10705]'
|
28
30
|
json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8)
|
29
31
|
e = assert_raise(JSON::ParserError) {
|
@@ -15,10 +15,14 @@ else
|
|
15
15
|
require 'oj'
|
16
16
|
Oj.mimic_JSON
|
17
17
|
|
18
|
+
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
19
|
+
# move objects around, helping to find object movement bugs.
|
18
20
|
if defined?(GC.verify_compaction_references) == 'method'
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2.0")
|
22
|
+
GC.verify_compaction_references(expand_heap: true, toward: :empty)
|
23
|
+
else
|
24
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
data/test/test_custom.rb
CHANGED
@@ -200,6 +200,8 @@ class CustomJuice < Minitest::Test
|
|
200
200
|
end
|
201
201
|
|
202
202
|
def test_deep_nest
|
203
|
+
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
204
|
+
|
203
205
|
begin
|
204
206
|
n = 10000
|
205
207
|
Oj.strict_load('[' * n + ']' * n)
|
@@ -258,6 +260,8 @@ class CustomJuice < Minitest::Test
|
|
258
260
|
end
|
259
261
|
|
260
262
|
def test_object
|
263
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
264
|
+
|
261
265
|
obj = Jeez.new(true, 58)
|
262
266
|
json = Oj.dump(obj, create_id: "^o", use_to_json: false, use_as_json: false, use_to_hash: false)
|
263
267
|
assert_equal(%|{"x":true,"y":58,"_z":"true"}|, json)
|
@@ -403,11 +407,15 @@ class CustomJuice < Minitest::Test
|
|
403
407
|
end
|
404
408
|
|
405
409
|
def test_range
|
410
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
411
|
+
|
406
412
|
obj = 3..8
|
407
413
|
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
408
414
|
end
|
409
415
|
|
410
416
|
def test_date
|
417
|
+
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
418
|
+
|
411
419
|
obj = Date.new(2017, 1, 5)
|
412
420
|
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
413
421
|
end
|
@@ -437,6 +445,8 @@ class CustomJuice < Minitest::Test
|
|
437
445
|
end
|
438
446
|
|
439
447
|
def test_datetime
|
448
|
+
skip 'TruffleRuby causes SEGV' if RUBY_ENGINE == 'truffleruby'
|
449
|
+
|
440
450
|
obj = DateTime.new(2017, 1, 5, 10, 20, 30)
|
441
451
|
dump_and_load(obj, false, :create_id => "^o", :create_additions => true)
|
442
452
|
end
|
@@ -480,6 +490,8 @@ class CustomJuice < Minitest::Test
|
|
480
490
|
end
|
481
491
|
|
482
492
|
def test_time
|
493
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
494
|
+
|
483
495
|
obj = Time.now()
|
484
496
|
dump_load_dump(obj, false, :time_format => :unix, :create_id => "^o", :create_additions => true)
|
485
497
|
dump_load_dump(obj, false, :time_format => :unix_zone, :create_id => "^o", :create_additions => true)
|
data/test/test_file.rb
CHANGED
@@ -125,13 +125,16 @@ class FileJuice < Minitest::Test
|
|
125
125
|
|
126
126
|
# Time
|
127
127
|
def test_time_object
|
128
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
129
|
+
|
128
130
|
t = Time.now()
|
129
131
|
Oj.default_options = { :mode => :object, :time_format => :unix_zone }
|
130
132
|
dump_and_load(t, false)
|
131
133
|
end
|
132
134
|
def test_time_object_early
|
133
|
-
|
134
|
-
|
135
|
+
skip 'Windows does not support dates before 1970.' if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
136
|
+
skip 'TruffleRuby fails this spec' if RUBY_ENGINE == 'truffleruby'
|
137
|
+
|
135
138
|
t = Time.xmlschema("1954-01-05T00:00:00.123456")
|
136
139
|
Oj.default_options = { :mode => :object, :time_format => :unix_zone }
|
137
140
|
dump_and_load(t, false)
|
@@ -166,6 +169,8 @@ class FileJuice < Minitest::Test
|
|
166
169
|
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
167
170
|
elsif 'jruby' == $ruby
|
168
171
|
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
172
|
+
elsif 'truffleruby' == $ruby
|
173
|
+
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
169
174
|
else
|
170
175
|
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
171
176
|
end
|
data/test/test_gc.rb
CHANGED
@@ -26,10 +26,12 @@ class GCTest < Minitest::Test
|
|
26
26
|
|
27
27
|
def setup
|
28
28
|
@default_options = Oj.default_options
|
29
|
+
GC.stress = true
|
29
30
|
end
|
30
31
|
|
31
32
|
def teardown
|
32
33
|
Oj.default_options = @default_options
|
34
|
+
GC.stress = false
|
33
35
|
end
|
34
36
|
|
35
37
|
# if no crash then the GC marking is working
|
@@ -41,9 +43,20 @@ class GCTest < Minitest::Test
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def test_parse_object_gc
|
46
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
47
|
+
|
44
48
|
g = Goo.new(0, nil)
|
45
49
|
100.times { |i| g = Goo.new(i, g) }
|
46
50
|
json = Oj.dump(g, :mode => :object)
|
47
51
|
Oj.object_load(json)
|
48
52
|
end
|
53
|
+
|
54
|
+
def test_parse_gc
|
55
|
+
json = '{"a":"Alpha","b":true,"c":12345,"d":[true,[false,[-123456789,null],3.9676,["Something else.",false],null]],"e":{"zero":null,"one":1,"two":2,"three":[3],"four":[0,1,2,3,4]},"f":null,"h":{"a":{"b":{"c":{"d":{"e":{"f":{"g":null}}}}}}},"i":[[[[[[[null]]]]]]]}'
|
56
|
+
|
57
|
+
50.times do
|
58
|
+
data = Oj.load(json)
|
59
|
+
assert_equal(json, Oj.dump(data))
|
60
|
+
end
|
61
|
+
end
|
49
62
|
end
|
data/test/test_integer_range.rb
CHANGED
@@ -23,18 +23,24 @@ class IntegerRangeTest < Minitest::Test
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_range
|
26
|
+
skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby'
|
27
|
+
|
26
28
|
test = {s: 0, s2: -1, s3: 1, u: -2, u2: 2, u3: 9007199254740993}
|
27
29
|
exp = '{"s":0,"s2":-1,"s3":1,"u":"-2","u2":"2","u3":"9007199254740993"}'
|
28
30
|
assert_equal(exp, Oj.dump(test, integer_range: (-1..1)))
|
29
31
|
end
|
30
32
|
|
31
33
|
def test_bignum
|
34
|
+
skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby'
|
35
|
+
|
32
36
|
test = {u: -10000000000000000000, u2: 10000000000000000000}
|
33
37
|
exp = '{"u":"-10000000000000000000","u2":"10000000000000000000"}'
|
34
38
|
assert_equal(exp, Oj.dump(test, integer_range: (-1..1)))
|
35
39
|
end
|
36
40
|
|
37
41
|
def test_valid_modes
|
42
|
+
skip 'TruffleRuby fails this spec with `ArgumentError: :integer_range must be a range of Fixnum.`' if RUBY_ENGINE == 'truffleruby'
|
43
|
+
|
38
44
|
test = {safe: 0, unsafe: 9007199254740993}
|
39
45
|
exp = '{"safe":0,"unsafe":"9007199254740993"}'
|
40
46
|
|
data/test/test_object.rb
CHANGED
@@ -224,7 +224,7 @@ class ObjectJuice < Minitest::Test
|
|
224
224
|
#=begin
|
225
225
|
if '3.1.0' <= RUBY_VERSION && !(RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/)
|
226
226
|
#Oj::debug_odd("teardown before GC.verify_compaction_references")
|
227
|
-
|
227
|
+
verify_gc_compaction
|
228
228
|
#Oj::debug_odd("teardown after GC.verify_compaction_references")
|
229
229
|
end
|
230
230
|
#=end
|
@@ -461,6 +461,8 @@ class ObjectJuice < Minitest::Test
|
|
461
461
|
end
|
462
462
|
|
463
463
|
def test_json_module_object
|
464
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
465
|
+
|
464
466
|
obj = One::Two::Three::Deep.new()
|
465
467
|
dump_and_load(obj, false)
|
466
468
|
end
|
@@ -631,11 +633,15 @@ class ObjectJuice < Minitest::Test
|
|
631
633
|
end
|
632
634
|
|
633
635
|
def test_json_object
|
636
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
637
|
+
|
634
638
|
obj = Jeez.new(true, 58)
|
635
639
|
dump_and_load(obj, false)
|
636
640
|
end
|
637
641
|
|
638
642
|
def test_json_object_create_deep
|
643
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
644
|
+
|
639
645
|
obj = One::Two::Three::Deep.new()
|
640
646
|
dump_and_load(obj, false)
|
641
647
|
end
|
@@ -672,6 +678,8 @@ class ObjectJuice < Minitest::Test
|
|
672
678
|
end
|
673
679
|
|
674
680
|
def test_json_anonymous_struct
|
681
|
+
skip 'TruffleRuby fails this spec with `TypeError: allocator undefined for Class`' if RUBY_ENGINE == 'truffleruby'
|
682
|
+
|
675
683
|
s = Struct.new(:x, :y)
|
676
684
|
obj = s.new(1, 2)
|
677
685
|
json = Oj.dump(obj, :indent => 2, :mode => :object)
|
@@ -694,6 +702,8 @@ class ObjectJuice < Minitest::Test
|
|
694
702
|
end
|
695
703
|
|
696
704
|
def test_json_object_object
|
705
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
706
|
+
|
697
707
|
obj = Jeez.new(true, 58)
|
698
708
|
json = Oj.dump(obj, mode: :object, indent: 2, ignore_under: true)
|
699
709
|
assert(%{{
|
@@ -713,6 +723,8 @@ class ObjectJuice < Minitest::Test
|
|
713
723
|
end
|
714
724
|
|
715
725
|
def test_to_hash_object_object
|
726
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
727
|
+
|
716
728
|
obj = Jazz.new(true, 58)
|
717
729
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
718
730
|
assert(%{{
|
@@ -732,6 +744,8 @@ class ObjectJuice < Minitest::Test
|
|
732
744
|
end
|
733
745
|
|
734
746
|
def test_as_json_object_object
|
747
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
748
|
+
|
735
749
|
obj = Orange.new(true, 58)
|
736
750
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
737
751
|
assert(%{{
|
@@ -751,6 +765,8 @@ class ObjectJuice < Minitest::Test
|
|
751
765
|
end
|
752
766
|
|
753
767
|
def test_object_object_no_cache
|
768
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
769
|
+
|
754
770
|
obj = Jam.new(true, 58)
|
755
771
|
json = Oj.dump(obj, :mode => :object, :indent => 2)
|
756
772
|
assert(%{{
|
@@ -779,6 +795,8 @@ class ObjectJuice < Minitest::Test
|
|
779
795
|
end
|
780
796
|
|
781
797
|
def test_exception
|
798
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
799
|
+
|
782
800
|
err = nil
|
783
801
|
begin
|
784
802
|
raise StandardError.new('A Message')
|
@@ -809,6 +827,8 @@ class ObjectJuice < Minitest::Test
|
|
809
827
|
end
|
810
828
|
|
811
829
|
def test_exception_subclass
|
830
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
831
|
+
|
812
832
|
err = nil
|
813
833
|
begin
|
814
834
|
raise SubX.new
|
@@ -830,6 +850,8 @@ class ObjectJuice < Minitest::Test
|
|
830
850
|
json = Oj.dump(1..7, :mode => :object, :indent => 0)
|
831
851
|
if 'rubinius' == $ruby
|
832
852
|
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
853
|
+
elsif 'truffleruby' == $ruby
|
854
|
+
assert(%{{"^O":"Range","begin":1,"end":7,"exclude_end?":false}} == json)
|
833
855
|
else
|
834
856
|
assert_equal(%{{"^u":["Range",1,7,false]}}, json)
|
835
857
|
end
|
@@ -895,6 +917,8 @@ class ObjectJuice < Minitest::Test
|
|
895
917
|
end
|
896
918
|
|
897
919
|
def test_circular_object
|
920
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
921
|
+
|
898
922
|
obj = Jeez.new(nil, 58)
|
899
923
|
obj.x = obj
|
900
924
|
json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
|
@@ -903,6 +927,8 @@ class ObjectJuice < Minitest::Test
|
|
903
927
|
end
|
904
928
|
|
905
929
|
def test_circular_object2
|
930
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
931
|
+
|
906
932
|
obj = Jam.new(nil, 58)
|
907
933
|
obj.x = obj
|
908
934
|
json = Oj.dump(obj, :mode => :object, :indent => 2, :circular => true)
|
@@ -925,6 +951,8 @@ class ObjectJuice < Minitest::Test
|
|
925
951
|
end
|
926
952
|
|
927
953
|
def test_circular
|
954
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
955
|
+
|
928
956
|
h = { 'a' => 7 }
|
929
957
|
obj = Jeez.new(h, 58)
|
930
958
|
obj.x['b'] = obj
|
@@ -935,6 +963,8 @@ class ObjectJuice < Minitest::Test
|
|
935
963
|
end
|
936
964
|
|
937
965
|
def test_circular2
|
966
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
967
|
+
|
938
968
|
h = { 'a' => 7 }
|
939
969
|
obj = Jam.new(h, 58)
|
940
970
|
obj.x['b'] = obj
|
@@ -947,6 +977,8 @@ class ObjectJuice < Minitest::Test
|
|
947
977
|
end
|
948
978
|
|
949
979
|
def test_omit_nil
|
980
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
981
|
+
|
950
982
|
jam = Jam.new({'a' => 1, 'b' => nil }, nil)
|
951
983
|
|
952
984
|
json = Oj.dump(jam, :omit_nil => true, :mode => :object)
|
@@ -1001,16 +1033,22 @@ class ObjectJuice < Minitest::Test
|
|
1001
1033
|
end
|
1002
1034
|
|
1003
1035
|
def test_auto_string
|
1036
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
1037
|
+
|
1004
1038
|
s = AutoStrung.new("Pete", true)
|
1005
1039
|
dump_and_load(s, false)
|
1006
1040
|
end
|
1007
1041
|
|
1008
1042
|
def test_auto_array
|
1043
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
1044
|
+
|
1009
1045
|
a = AutoArray.new([1, 'abc', nil], true)
|
1010
1046
|
dump_and_load(a, false)
|
1011
1047
|
end
|
1012
1048
|
|
1013
1049
|
def test_auto_hash
|
1050
|
+
skip 'TruffleRuby fails this spec with `RuntimeError: rb_ivar_foreach not implemented`' if RUBY_ENGINE == 'truffleruby'
|
1051
|
+
|
1014
1052
|
h = AutoHash.new(nil, true)
|
1015
1053
|
h['a'] = 1
|
1016
1054
|
h['b'] = 2
|
data/test/test_parser_saj.rb
CHANGED
@@ -149,6 +149,17 @@ class SajTest < Minitest::Test
|
|
149
149
|
assert_equal((12345.6789e7 * 10000).to_i, (handler.calls[0][1] * 10000).to_i)
|
150
150
|
end
|
151
151
|
|
152
|
+
def test_bignum
|
153
|
+
handler = AllSaj.new()
|
154
|
+
json = %{-11.899999999999999}
|
155
|
+
p = Oj::Parser.new(:saj)
|
156
|
+
p.handler = handler
|
157
|
+
p.parse(json)
|
158
|
+
assert_equal(1, handler.calls.size)
|
159
|
+
assert_equal(:add_value, handler.calls[0][0])
|
160
|
+
assert_equal(-118999, (handler.calls[0][1] * 10000).to_i)
|
161
|
+
end
|
162
|
+
|
152
163
|
def test_array_empty
|
153
164
|
handler = AllSaj.new()
|
154
165
|
json = %{[]}
|
data/test/test_scp.rb
CHANGED
@@ -320,8 +320,8 @@ class ScpTest < Minitest::Test
|
|
320
320
|
end
|
321
321
|
|
322
322
|
def test_pipe
|
323
|
-
|
324
|
-
|
323
|
+
skip ' Windows does not support fork' if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
324
|
+
skip 'TruffleRuby fails this spec with `NotImplementedError: fork is not available`' if RUBY_ENGINE == 'truffleruby'
|
325
325
|
|
326
326
|
handler = AllHandler.new()
|
327
327
|
json = %{{"one":true,"two":false}}
|
@@ -357,8 +357,8 @@ class ScpTest < Minitest::Test
|
|
357
357
|
end
|
358
358
|
|
359
359
|
def test_pipe_close
|
360
|
-
|
361
|
-
|
360
|
+
skip 'Windows does not support fork' if RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
361
|
+
skip 'TruffleRuby fails this spec with `NotImplementedError: fork is not available`' if RUBY_ENGINE == 'truffleruby'
|
362
362
|
|
363
363
|
json = %{{"one":true,"two":false}}
|
364
364
|
IO.pipe do |read_io, write_io|
|
data/test/test_strict.rb
CHANGED
data/test/test_wab.rb
CHANGED
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.13.
|
4
|
+
version: 3.13.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07
|
11
|
+
date: 2022-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|