oj 3.14.3 → 3.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/ext/oj/code.c +3 -10
- data/ext/oj/compat.c +5 -18
- data/ext/oj/custom.c +10 -28
- data/ext/oj/dump.c +40 -10
- data/ext/oj/dump.h +1 -4
- data/ext/oj/extconf.rb +4 -2
- data/ext/oj/fast.c +3 -6
- data/ext/oj/mimic_json.c +21 -1
- data/ext/oj/object.c +7 -21
- data/ext/oj/oj.c +24 -4
- data/ext/oj/oj.h +10 -6
- data/ext/oj/parse.c +3 -5
- data/ext/oj/parse.h +16 -14
- data/ext/oj/parser.h +2 -2
- data/ext/oj/reader.c +1 -3
- data/ext/oj/saj.c +1 -1
- data/ext/oj/strict.c +9 -27
- data/ext/oj/wab.c +9 -27
- data/lib/oj/active_support_helper.rb +2 -3
- data/lib/oj/json.rb +156 -149
- data/lib/oj/mimic.rb +3 -1
- data/lib/oj/version.rb +1 -1
- data/lib/oj.rb +3 -0
- data/pages/Options.md +4 -0
- data/test/_test_active.rb +8 -8
- data/test/_test_active_mimic.rb +7 -7
- data/test/_test_mimic_rails.rb +17 -19
- data/test/files.rb +14 -14
- data/test/foo.rb +15 -10
- data/test/helper.rb +4 -4
- data/test/mem.rb +8 -7
- data/test/perf.rb +21 -26
- data/test/perf_compat.rb +30 -32
- data/test/perf_dump.rb +27 -27
- data/test/perf_fast.rb +80 -82
- data/test/perf_file.rb +27 -29
- data/test/perf_object.rb +65 -68
- data/test/perf_once.rb +8 -7
- data/test/perf_parser.rb +40 -46
- data/test/perf_saj.rb +46 -53
- data/test/perf_scp.rb +57 -69
- data/test/perf_simple.rb +40 -38
- data/test/perf_strict.rb +68 -70
- data/test/perf_wab.rb +67 -69
- data/test/prec.rb +3 -3
- data/test/sample.rb +16 -15
- data/test/sample_json.rb +8 -7
- data/test/test_compat.rb +44 -46
- data/test/test_custom.rb +56 -42
- data/test/test_debian.rb +6 -9
- data/test/test_fast.rb +78 -72
- data/test/test_file.rb +16 -21
- 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 +18 -20
- data/test/test_object.rb +76 -86
- data/test/test_parser.rb +4 -4
- data/test/test_parser_debug.rb +4 -4
- data/test/test_parser_saj.rb +31 -31
- data/test/test_parser_usual.rb +3 -3
- data/test/test_rails.rb +2 -2
- data/test/test_saj.rb +8 -8
- data/test/test_scp.rb +29 -29
- data/test/test_strict.rb +25 -31
- data/test/test_various.rb +121 -75
- data/test/test_wab.rb +43 -42
- data/test/test_writer.rb +46 -46
- data/test/tests.rb +7 -7
- data/test/tests_mimic.rb +6 -6
- data/test/tests_mimic_addition.rb +6 -6
- metadata +3 -6
- data/test/bar.rb +0 -11
- data/test/baz.rb +0 -16
- data/test/bug.rb +0 -16
- data/test/zoo.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 257582096951b3c4db4b4979c49afd542ae855ba454bd6d51dcb1a69f68c2405
|
4
|
+
data.tar.gz: d835a958d019f7034e93d3f97ca1829fad74a4e26743f6a8b2b581c03ac9f14a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 374e55547de2db4b2199c05bebe5fa74953021883f7f609e328466c076016817b0cb8a7be03ead9c68b3fe4895eb5de0bcd60e1384ff7f1a5f7cd480824faba0
|
7
|
+
data.tar.gz: ec9cf41116602a51c49ff73ba6fc39ecbb501d51cbab0a6065bb38d2ac15a7f42332dc66f0d97df40bea6da5fafbc15209d06039180829c4c4b299b0e138676e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.15.1 - 2023-07-30
|
4
|
+
|
5
|
+
- Add protection against some using `require 'oj/json`, an internal file.
|
6
|
+
|
7
|
+
- Fixed non-json errors when in compat mode.
|
8
|
+
|
9
|
+
## 3.15.0 - 2023-06-02
|
10
|
+
|
11
|
+
- Added `omit_null_byte` option when dumping.
|
12
|
+
|
3
13
|
## 3.14.3 - 2023-04-07
|
4
14
|
|
5
15
|
- Fixed compat parse with optimized Hash when parsing a JSON::GenericObject.
|
data/ext/oj/code.c
CHANGED
@@ -185,24 +185,17 @@ void oj_code_attrs(VALUE obj, Attr attrs, int depth, Out out, bool with_class) {
|
|
185
185
|
} else {
|
186
186
|
char buf[32];
|
187
187
|
char *b = buf + sizeof(buf) - 1;
|
188
|
-
|
188
|
+
bool neg = false;
|
189
189
|
long num = attrs->num;
|
190
190
|
size_t cnt = 0;
|
191
191
|
|
192
192
|
if (0 > num) {
|
193
|
-
neg =
|
193
|
+
neg = true;
|
194
194
|
num = -num;
|
195
195
|
}
|
196
196
|
*b-- = '\0';
|
197
197
|
if (0 < num) {
|
198
|
-
|
199
|
-
*b = (num % 10) + '0';
|
200
|
-
}
|
201
|
-
if (neg) {
|
202
|
-
*b = '-';
|
203
|
-
} else {
|
204
|
-
b++;
|
205
|
-
}
|
198
|
+
b = oj_longlong_to_string(num, neg, b);
|
206
199
|
} else {
|
207
200
|
*b = '0';
|
208
201
|
}
|
data/ext/oj/compat.c
CHANGED
@@ -13,32 +13,19 @@
|
|
13
13
|
#include "trace.h"
|
14
14
|
|
15
15
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
16
|
-
const char
|
17
|
-
int
|
18
|
-
Val
|
19
|
-
volatile VALUE rkey = kval->key_val;
|
16
|
+
const char *key = kval->key;
|
17
|
+
int klen = kval->klen;
|
18
|
+
Val parent = stack_peek(&pi->stack);
|
20
19
|
|
21
|
-
if (Qundef ==
|
20
|
+
if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
|
22
21
|
*pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
|
23
22
|
0 == strncmp(pi->options.create_id, key, klen)) {
|
24
23
|
parent->classname = oj_strndup(str, len);
|
25
24
|
parent->clen = len;
|
26
25
|
} else {
|
27
26
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
27
|
+
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
28
28
|
|
29
|
-
if (Qundef == rkey) {
|
30
|
-
if (Yes != pi->options.cache_keys) {
|
31
|
-
if (Yes == pi->options.sym_key) {
|
32
|
-
rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
|
33
|
-
} else {
|
34
|
-
rkey = rb_utf8_str_new(key, klen);
|
35
|
-
}
|
36
|
-
} else if (Yes == pi->options.sym_key) {
|
37
|
-
rkey = oj_sym_intern(key, klen);
|
38
|
-
} else {
|
39
|
-
rkey = oj_str_intern(key, klen);
|
40
|
-
}
|
41
|
-
}
|
42
29
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
43
30
|
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
|
44
31
|
|
data/ext/oj/custom.c
CHANGED
@@ -889,12 +889,11 @@ void oj_dump_custom_val(VALUE obj, int depth, Out out, bool as_ok) {
|
|
889
889
|
///// load functions /////
|
890
890
|
|
891
891
|
static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, const char *orig) {
|
892
|
-
const char
|
893
|
-
int
|
894
|
-
Val
|
895
|
-
volatile VALUE rkey = kval->key_val;
|
892
|
+
const char *key = kval->key;
|
893
|
+
int klen = kval->klen;
|
894
|
+
Val parent = stack_peek(&pi->stack);
|
896
895
|
|
897
|
-
if (Qundef ==
|
896
|
+
if (Qundef == kval->key_val && Yes == pi->options.create_ok && NULL != pi->options.create_id &&
|
898
897
|
*pi->options.create_id == *key && (int)pi->options.create_id_len == klen &&
|
899
898
|
0 == strncmp(pi->options.create_id, key, klen)) {
|
900
899
|
parent->clas = oj_name2class(pi, str, len, false, rb_eArgError);
|
@@ -907,15 +906,8 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
907
906
|
}
|
908
907
|
} else {
|
909
908
|
volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
|
910
|
-
|
909
|
+
volatile VALUE rkey = oj_calc_hash_key(pi, kval);
|
911
910
|
|
912
|
-
if (Qundef == rkey) {
|
913
|
-
if (Yes == pi->options.sym_key) {
|
914
|
-
rkey = ID2SYM(rb_intern3(key, klen, oj_utf8_encoding));
|
915
|
-
} else {
|
916
|
-
rkey = rb_utf8_str_new(key, klen);
|
917
|
-
}
|
918
|
-
}
|
919
911
|
if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
|
920
912
|
VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
|
921
913
|
|
@@ -937,9 +929,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
|
|
937
929
|
break;
|
938
930
|
default: break;
|
939
931
|
}
|
940
|
-
|
941
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rstr);
|
942
|
-
}
|
932
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rstr);
|
943
933
|
}
|
944
934
|
}
|
945
935
|
|
@@ -998,9 +988,7 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
|
|
998
988
|
break;
|
999
989
|
default: break;
|
1000
990
|
}
|
1001
|
-
|
1002
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
1003
|
-
}
|
991
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
1004
992
|
}
|
1005
993
|
|
1006
994
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -1011,9 +999,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
|
1011
999
|
case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
|
1012
1000
|
default: break;
|
1013
1001
|
}
|
1014
|
-
|
1015
|
-
oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
|
1016
|
-
}
|
1002
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_value", pi, value);
|
1017
1003
|
}
|
1018
1004
|
|
1019
1005
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
@@ -1021,9 +1007,7 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
|
|
1021
1007
|
volatile VALUE rval = oj_num_as_value(ni);
|
1022
1008
|
|
1023
1009
|
rb_ary_push(parent->val, rval);
|
1024
|
-
|
1025
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
1026
|
-
}
|
1010
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
1027
1011
|
}
|
1028
1012
|
|
1029
1013
|
static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
@@ -1038,9 +1022,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
1038
1022
|
}
|
1039
1023
|
}
|
1040
1024
|
rb_ary_push(stack_peek(&pi->stack)->val, rstr);
|
1041
|
-
|
1042
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rstr);
|
1043
|
-
}
|
1025
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rstr);
|
1044
1026
|
}
|
1045
1027
|
|
1046
1028
|
void oj_set_custom_callbacks(ParseInfo pi) {
|
data/ext/oj/dump.c
CHANGED
@@ -857,6 +857,9 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
|
|
857
857
|
break;
|
858
858
|
case '6': // control characters
|
859
859
|
if (*(uint8_t *)str < 0x80) {
|
860
|
+
if (0 == (uint8_t)*str && out->opts->dump_opts.omit_null_byte) {
|
861
|
+
break;
|
862
|
+
}
|
860
863
|
APPEND_CHARS(out->cur, "\\u00", 4);
|
861
864
|
dump_hex((uint8_t)*str, out);
|
862
865
|
} else {
|
@@ -995,11 +998,45 @@ void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
|
|
995
998
|
*out->cur = '\0';
|
996
999
|
}
|
997
1000
|
|
1001
|
+
static const char digits_table[] = "\
|
1002
|
+
00010203040506070809\
|
1003
|
+
10111213141516171819\
|
1004
|
+
20212223242526272829\
|
1005
|
+
30313233343536373839\
|
1006
|
+
40414243444546474849\
|
1007
|
+
50515253545556575859\
|
1008
|
+
60616263646566676869\
|
1009
|
+
70717273747576777879\
|
1010
|
+
80818283848586878889\
|
1011
|
+
90919293949596979899";
|
1012
|
+
|
1013
|
+
char *oj_longlong_to_string(long long num, bool negative, char *buf) {
|
1014
|
+
while (100 <= num) {
|
1015
|
+
unsigned idx = num % 100 * 2;
|
1016
|
+
*buf-- = digits_table[idx + 1];
|
1017
|
+
*buf-- = digits_table[idx];
|
1018
|
+
num /= 100;
|
1019
|
+
}
|
1020
|
+
if (num < 10) {
|
1021
|
+
*buf-- = num + '0';
|
1022
|
+
} else {
|
1023
|
+
*buf-- = digits_table[num * 2 + 1];
|
1024
|
+
*buf-- = digits_table[num * 2];
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
if (negative) {
|
1028
|
+
*buf = '-';
|
1029
|
+
} else {
|
1030
|
+
buf++;
|
1031
|
+
}
|
1032
|
+
return buf;
|
1033
|
+
}
|
1034
|
+
|
998
1035
|
void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
999
1036
|
char buf[32];
|
1000
1037
|
char *b = buf + sizeof(buf) - 1;
|
1001
1038
|
long long num = NUM2LL(obj);
|
1002
|
-
|
1039
|
+
bool neg = false;
|
1003
1040
|
size_t cnt = 0;
|
1004
1041
|
bool dump_as_string = false;
|
1005
1042
|
|
@@ -1008,7 +1045,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1008
1045
|
dump_as_string = true;
|
1009
1046
|
}
|
1010
1047
|
if (0 > num) {
|
1011
|
-
neg =
|
1048
|
+
neg = true;
|
1012
1049
|
num = -num;
|
1013
1050
|
}
|
1014
1051
|
*b-- = '\0';
|
@@ -1017,14 +1054,7 @@ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
|
|
1017
1054
|
*b-- = '"';
|
1018
1055
|
}
|
1019
1056
|
if (0 < num) {
|
1020
|
-
|
1021
|
-
*b = (num % 10) + '0';
|
1022
|
-
}
|
1023
|
-
if (neg) {
|
1024
|
-
*b = '-';
|
1025
|
-
} else {
|
1026
|
-
b++;
|
1027
|
-
}
|
1057
|
+
b = oj_longlong_to_string(num, neg, b);
|
1028
1058
|
} else {
|
1029
1059
|
*b = '0';
|
1030
1060
|
}
|
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
|
}
|
data/ext/oj/extconf.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'mkmf'
|
2
4
|
require 'rbconfig'
|
3
5
|
|
@@ -6,7 +8,7 @@ dir_config(extension_name)
|
|
6
8
|
|
7
9
|
parts = RUBY_DESCRIPTION.split(' ')
|
8
10
|
type = parts[0]
|
9
|
-
type = type[4
|
11
|
+
type = type[4..] if type.start_with?('tcs-')
|
10
12
|
is_windows = RbConfig::CONFIG['host_os'] =~ /(mingw|mswin)/
|
11
13
|
platform = RUBY_PLATFORM
|
12
14
|
version = RUBY_VERSION.split('.')
|
@@ -56,7 +58,7 @@ dflags.each do |k, v|
|
|
56
58
|
end
|
57
59
|
|
58
60
|
$CPPFLAGS += ' -Wall'
|
59
|
-
#puts "*** $CPPFLAGS: #{$CPPFLAGS}"
|
61
|
+
# puts "*** $CPPFLAGS: #{$CPPFLAGS}"
|
60
62
|
# Adding the __attribute__ flag only works with gcc compilers and even then it
|
61
63
|
# does not work to check args with varargs so just remove the check.
|
62
64
|
CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/)
|
data/ext/oj/fast.c
CHANGED
@@ -40,7 +40,7 @@ typedef struct _doc {
|
|
40
40
|
Leaf *where; // points to current location
|
41
41
|
Leaf where_path[MAX_STACK]; // points to head of path
|
42
42
|
char *json;
|
43
|
-
unsigned long size;
|
43
|
+
unsigned long size; // number of leaves/branches in the doc
|
44
44
|
VALUE self;
|
45
45
|
Batch batches;
|
46
46
|
struct _batch batch0;
|
@@ -114,10 +114,7 @@ inline static char *ulong_fill(char *s, size_t num) {
|
|
114
114
|
char *b = buf + sizeof(buf) - 1;
|
115
115
|
|
116
116
|
*b-- = '\0';
|
117
|
-
|
118
|
-
*b = (num % 10) + '0';
|
119
|
-
}
|
120
|
-
b++;
|
117
|
+
b = oj_longlong_to_string((long long)num, false, b);
|
121
118
|
if ('\0' == *b) {
|
122
119
|
b--;
|
123
120
|
*b = '0';
|
@@ -576,7 +573,7 @@ static char *read_quoted_value(ParseInfo pi) {
|
|
576
573
|
char *h = pi->s; // head
|
577
574
|
char *t = h; // tail
|
578
575
|
|
579
|
-
h++;
|
576
|
+
h++; // skip quote character
|
580
577
|
t++;
|
581
578
|
value = h;
|
582
579
|
for (; '"' != *h; h++, t++) {
|
data/ext/oj/mimic_json.c
CHANGED
@@ -574,7 +574,6 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
574
574
|
if (T_HASH != rb_type(ropts)) {
|
575
575
|
rb_raise(rb_eArgError, "options must be a hash.");
|
576
576
|
}
|
577
|
-
|
578
577
|
rb_hash_foreach(ropts, parse_options_cb, (VALUE)&pi);
|
579
578
|
v = rb_hash_lookup(ropts, oj_max_nesting_sym);
|
580
579
|
if (Qtrue == v) {
|
@@ -738,6 +737,7 @@ static struct _options mimic_object_to_json_options = {0, // indent
|
|
738
737
|
0, // array_size
|
739
738
|
RaiseNan, // nan_dump
|
740
739
|
false, // omit_nil
|
740
|
+
false, // omit_null_byte
|
741
741
|
100, // max_depth
|
742
742
|
},
|
743
743
|
{
|
@@ -791,28 +791,48 @@ void oj_mimic_json_methods(VALUE json) {
|
|
791
791
|
VALUE json_error;
|
792
792
|
VALUE generator;
|
793
793
|
VALUE ext;
|
794
|
+
VALUE verbose;
|
795
|
+
|
796
|
+
// rb_undef_method doesn't work for modules or maybe sometimes
|
797
|
+
// doesn't. Anyway setting verbose should hide the warning.
|
798
|
+
verbose = rb_gv_get("$VERBOSE");
|
799
|
+
rb_gv_set("$VERBOSE", Qfalse);
|
794
800
|
|
801
|
+
rb_undef_method(json, "create_id=");
|
795
802
|
rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
|
803
|
+
rb_undef_method(json, "create_id");
|
796
804
|
rb_define_module_function(json, "create_id", mimic_create_id, 0);
|
797
805
|
|
806
|
+
rb_undef_method(json, "dump");
|
798
807
|
rb_define_module_function(json, "dump", mimic_dump, -1);
|
808
|
+
rb_undef_method(json, "load");
|
799
809
|
rb_define_module_function(json, "load", mimic_load, -1);
|
800
810
|
rb_define_module_function(json, "restore", mimic_load, -1);
|
811
|
+
rb_undef_method(json, "recurse_proc");
|
801
812
|
rb_define_module_function(json, "recurse_proc", mimic_recurse_proc, 1);
|
813
|
+
rb_undef_method(json, "[]");
|
802
814
|
rb_define_module_function(json, "[]", mimic_dump_load, -1);
|
803
815
|
|
816
|
+
rb_undef_method(json, "generate");
|
804
817
|
rb_define_module_function(json, "generate", oj_mimic_generate, -1);
|
818
|
+
rb_undef_method(json, "fast_generate");
|
805
819
|
rb_define_module_function(json, "fast_generate", oj_mimic_generate, -1);
|
820
|
+
rb_undef_method(json, "pretty_generate");
|
806
821
|
rb_define_module_function(json, "pretty_generate", oj_mimic_pretty_generate, -1);
|
807
822
|
// For older versions of JSON, the deprecated unparse methods.
|
823
|
+
rb_undef_method(json, "unparse");
|
808
824
|
rb_define_module_function(json, "unparse", oj_mimic_generate, -1);
|
809
825
|
rb_define_module_function(json, "fast_unparse", oj_mimic_generate, -1);
|
810
826
|
rb_define_module_function(json, "pretty_unparse", oj_mimic_pretty_generate, -1);
|
811
827
|
|
828
|
+
rb_undef_method(json, "parse");
|
812
829
|
rb_define_module_function(json, "parse", oj_mimic_parse, -1);
|
830
|
+
rb_undef_method(json, "parse!");
|
813
831
|
rb_define_module_function(json, "parse!", mimic_parse_bang, -1);
|
814
832
|
|
833
|
+
rb_undef_method(json, "state");
|
815
834
|
rb_define_module_function(json, "state", mimic_state, 0);
|
835
|
+
rb_gv_set("$VERBOSE", verbose);
|
816
836
|
|
817
837
|
if (rb_const_defined_at(json, rb_intern("JSONError"))) {
|
818
838
|
json_error = rb_const_get(json, rb_intern("JSONError"));
|
data/ext/oj/object.c
CHANGED
@@ -446,9 +446,7 @@ WHICH_TYPE:
|
|
446
446
|
rb_class2name(rb_obj_class(parent->val)));
|
447
447
|
return;
|
448
448
|
}
|
449
|
-
|
450
|
-
oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
|
451
|
-
}
|
449
|
+
TRACE_PARSE_CALL(pi->options.trace, "set_string", pi, rval);
|
452
450
|
}
|
453
451
|
|
454
452
|
static void hash_set_num(ParseInfo pi, Val kval, NumInfo ni) {
|
@@ -517,9 +515,7 @@ WHICH_TYPE:
|
|
517
515
|
rb_class2name(rb_obj_class(parent->val)));
|
518
516
|
return;
|
519
517
|
}
|
520
|
-
|
521
|
-
oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, rval);
|
522
|
-
}
|
518
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_number", pi, rval);
|
523
519
|
}
|
524
520
|
|
525
521
|
static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
|
@@ -603,9 +599,7 @@ WHICH_TYPE:
|
|
603
599
|
rb_class2name(rb_obj_class(parent->val)));
|
604
600
|
return;
|
605
601
|
}
|
606
|
-
|
607
|
-
oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, value);
|
608
|
-
}
|
602
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_value", pi, value);
|
609
603
|
}
|
610
604
|
|
611
605
|
static VALUE start_hash(ParseInfo pi) {
|
@@ -651,32 +645,24 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
|
|
651
645
|
}
|
652
646
|
rval = str_to_value(pi, str, len, orig);
|
653
647
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
654
|
-
|
655
|
-
oj_trace_parse_call("append_string", pi, __FILE__, __LINE__, rval);
|
656
|
-
}
|
648
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_string", pi, rval);
|
657
649
|
}
|
658
650
|
|
659
651
|
static void array_append_num(ParseInfo pi, NumInfo ni) {
|
660
652
|
volatile VALUE rval = oj_num_as_value(ni);
|
661
653
|
|
662
654
|
rb_ary_push(stack_peek(&pi->stack)->val, rval);
|
663
|
-
|
664
|
-
oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
|
665
|
-
}
|
655
|
+
TRACE_PARSE_CALL(pi->options.trace, "append_number", pi, rval);
|
666
656
|
}
|
667
657
|
|
668
658
|
static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
|
669
659
|
pi->stack.head->val = str_to_value(pi, str, len, orig);
|
670
|
-
|
671
|
-
oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
|
672
|
-
}
|
660
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_string", pi, pi->stack.head->val);
|
673
661
|
}
|
674
662
|
|
675
663
|
static void add_num(ParseInfo pi, NumInfo ni) {
|
676
664
|
pi->stack.head->val = oj_num_as_value(ni);
|
677
|
-
|
678
|
-
oj_trace_parse_call("add_num", pi, __FILE__, __LINE__, pi->stack.head->val);
|
679
|
-
}
|
665
|
+
TRACE_PARSE_CALL(pi->options.trace, "add_num", pi, pi->stack.head->val);
|
680
666
|
}
|
681
667
|
|
682
668
|
void oj_set_object_callbacks(ParseInfo pi) {
|
data/ext/oj/oj.c
CHANGED
@@ -135,6 +135,7 @@ static VALUE newline_sym;
|
|
135
135
|
static VALUE nilnil_sym;
|
136
136
|
static VALUE null_sym;
|
137
137
|
static VALUE object_sym;
|
138
|
+
static VALUE omit_null_byte_sym;
|
138
139
|
static VALUE omit_nil_sym;
|
139
140
|
static VALUE rails_sym;
|
140
141
|
static VALUE raise_sym;
|
@@ -222,6 +223,7 @@ struct _options oj_default_options = {
|
|
222
223
|
0, // array_size
|
223
224
|
AutoNan, // nan_dump
|
224
225
|
false, // omit_nil
|
226
|
+
false, // omit_null_byte
|
225
227
|
MAX_DEPTH, // max_depth
|
226
228
|
},
|
227
229
|
{
|
@@ -230,7 +232,7 @@ struct _options oj_default_options = {
|
|
230
232
|
NULL, // tail
|
231
233
|
{'\0'}, // err
|
232
234
|
},
|
233
|
-
NULL,
|
235
|
+
NULL, // ignore
|
234
236
|
};
|
235
237
|
|
236
238
|
/* Document-method: default_options()
|
@@ -291,6 +293,7 @@ struct _options oj_default_options = {
|
|
291
293
|
*used
|
292
294
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
293
295
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
|
296
|
+
* - *:omit_null_byte* [_true_|_false_] if true null bytes in strings will be omitted when dumping
|
294
297
|
* - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
|
295
298
|
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
|
296
299
|
*object or custom mode.
|
@@ -384,6 +387,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
384
387
|
opts,
|
385
388
|
cache_keys_sym,
|
386
389
|
(Yes == oj_default_options.cache_keys) ? Qtrue : ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
|
390
|
+
|
387
391
|
switch (oj_default_options.mode) {
|
388
392
|
case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
|
389
393
|
case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
|
@@ -459,6 +463,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
459
463
|
default: rb_hash_aset(opts, nan_sym, auto_sym); break;
|
460
464
|
}
|
461
465
|
rb_hash_aset(opts, omit_nil_sym, oj_default_options.dump_opts.omit_nil ? Qtrue : Qfalse);
|
466
|
+
rb_hash_aset(opts, omit_null_byte_sym, oj_default_options.dump_opts.omit_null_byte ? Qtrue : Qfalse);
|
462
467
|
rb_hash_aset(opts, oj_hash_class_sym, oj_default_options.hash_class);
|
463
468
|
rb_hash_aset(opts, oj_array_class_sym, oj_default_options.array_class);
|
464
469
|
|
@@ -865,6 +870,17 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
865
870
|
} else {
|
866
871
|
rb_raise(rb_eArgError, ":omit_nil must be true or false.");
|
867
872
|
}
|
873
|
+
} else if (omit_null_byte_sym == k) {
|
874
|
+
if (Qnil == v) {
|
875
|
+
return ST_CONTINUE;
|
876
|
+
}
|
877
|
+
if (Qtrue == v) {
|
878
|
+
copts->dump_opts.omit_null_byte = true;
|
879
|
+
} else if (Qfalse == v) {
|
880
|
+
copts->dump_opts.omit_null_byte = false;
|
881
|
+
} else {
|
882
|
+
rb_raise(rb_eArgError, ":omit_null_byte must be true or false.");
|
883
|
+
}
|
868
884
|
} else if (oj_ascii_only_sym == k) {
|
869
885
|
// This is here only for backwards compatibility with the original Oj.
|
870
886
|
if (Qtrue == v) {
|
@@ -1278,8 +1294,9 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1278
1294
|
|
1279
1295
|
oj_out_init(arg.out);
|
1280
1296
|
|
1281
|
-
arg.out->omit_nil
|
1282
|
-
arg.out->
|
1297
|
+
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1298
|
+
arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
|
1299
|
+
arg.out->caller = CALLER_DUMP;
|
1283
1300
|
|
1284
1301
|
return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
|
1285
1302
|
}
|
@@ -1326,7 +1343,8 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1326
1343
|
|
1327
1344
|
oj_out_init(&out);
|
1328
1345
|
|
1329
|
-
out.omit_nil
|
1346
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1347
|
+
out.omit_null_byte = copts.dump_opts.omit_null_byte;
|
1330
1348
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1331
1349
|
// it is.
|
1332
1350
|
oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
|
@@ -1967,6 +1985,8 @@ void Init_oj(void) {
|
|
1967
1985
|
rb_gc_register_address(&oj_quirks_mode_sym);
|
1968
1986
|
oj_safe_sym = ID2SYM(rb_intern("safe"));
|
1969
1987
|
rb_gc_register_address(&oj_safe_sym);
|
1988
|
+
omit_null_byte_sym = ID2SYM(rb_intern("omit_null_byte"));
|
1989
|
+
rb_gc_register_address(&omit_null_byte_sym);
|
1970
1990
|
oj_space_before_sym = ID2SYM(rb_intern("space_before"));
|
1971
1991
|
rb_gc_register_address(&oj_space_before_sym);
|
1972
1992
|
oj_space_sym = ID2SYM(rb_intern("space"));
|
data/ext/oj/oj.h
CHANGED
@@ -124,6 +124,7 @@ typedef struct _dumpOpts {
|
|
124
124
|
uint8_t array_size;
|
125
125
|
char nan_dump; // NanDump
|
126
126
|
bool omit_nil;
|
127
|
+
bool omit_null_byte;
|
127
128
|
int max_depth;
|
128
129
|
} *DumpOpts;
|
129
130
|
|
@@ -199,6 +200,7 @@ typedef struct _out {
|
|
199
200
|
uint32_t hash_cnt;
|
200
201
|
bool allocated;
|
201
202
|
bool omit_nil;
|
203
|
+
bool omit_null_byte;
|
202
204
|
int argc;
|
203
205
|
VALUE *argv;
|
204
206
|
DumpCaller caller; // used for the mimic json only
|
@@ -260,12 +262,13 @@ extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
|
|
260
262
|
extern bool oj_hash_has_key(VALUE hash, VALUE key);
|
261
263
|
extern void oj_parse_options(VALUE ropts, Options copts);
|
262
264
|
|
263
|
-
extern void
|
264
|
-
extern void
|
265
|
-
extern void
|
266
|
-
extern void
|
267
|
-
extern void
|
268
|
-
extern void
|
265
|
+
extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
|
266
|
+
extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
|
267
|
+
extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
|
268
|
+
extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
|
269
|
+
extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
|
270
|
+
extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
|
271
|
+
extern char *oj_longlong_to_string(long long num, bool negative, char *buf);
|
269
272
|
|
270
273
|
extern void oj_str_writer_push_key(StrWriter sw, const char *key);
|
271
274
|
extern void oj_str_writer_push_object(StrWriter sw, const char *key);
|
@@ -323,6 +326,7 @@ extern VALUE oj_max_nesting_sym;
|
|
323
326
|
extern VALUE oj_object_class_sym;
|
324
327
|
extern VALUE oj_object_nl_sym;
|
325
328
|
extern VALUE oj_quirks_mode_sym;
|
329
|
+
extern VALUE oj_skip_null_byte_sym;
|
326
330
|
extern VALUE oj_space_before_sym;
|
327
331
|
extern VALUE oj_space_sym;
|
328
332
|
extern VALUE oj_symbolize_names_sym;
|
data/ext/oj/parse.c
CHANGED
@@ -426,6 +426,7 @@ static void read_num(ParseInfo pi) {
|
|
426
426
|
struct _numInfo ni;
|
427
427
|
Val parent = stack_peek(&pi->stack);
|
428
428
|
|
429
|
+
ni.pi = pi;
|
429
430
|
ni.str = pi->cur;
|
430
431
|
ni.i = 0;
|
431
432
|
ni.num = 0;
|
@@ -709,10 +710,7 @@ void oj_parse2(ParseInfo pi) {
|
|
709
710
|
case '[': array_start(pi); break;
|
710
711
|
case ']': array_end(pi); break;
|
711
712
|
case ',': comma(pi); break;
|
712
|
-
case '"':
|
713
|
-
read_str(pi);
|
714
|
-
break;
|
715
|
-
// case '+':
|
713
|
+
case '"': read_str(pi); break;
|
716
714
|
case '+':
|
717
715
|
if (CompatMode == pi->options.mode) {
|
718
716
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
|
@@ -877,7 +875,7 @@ oj_num_as_value(NumInfo ni) {
|
|
877
875
|
double d = strtod(ni->str, &end);
|
878
876
|
|
879
877
|
if ((long)ni->len != (long)(end - ni->str)) {
|
880
|
-
rb_raise(
|
878
|
+
rb_raise(ni->pi->err_class, "Invalid float");
|
881
879
|
}
|
882
880
|
rnum = rb_float_new(d);
|
883
881
|
}
|