oj 3.17.0 → 3.17.1
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 +4 -0
- data/README.md +0 -16
- data/ext/oj/dump.c +8 -8
- data/ext/oj/fast.c +19 -12
- data/ext/oj/mimic_json.c +1 -0
- data/ext/oj/oj.c +26 -0
- data/ext/oj/oj.h +38 -37
- data/ext/oj/parse.c +20 -0
- data/ext/oj/parser.c +37 -38
- data/ext/oj/sparse.c +3 -0
- data/ext/oj/wab.c +1 -1
- data/lib/oj/version.rb +1 -1
- 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: a7515f34ac9c85f3e60f14c886bf3701f41fd077bdc518c71c6125e6ca7913db
|
|
4
|
+
data.tar.gz: f4a5cab57b8fc728e7ec4aac4dbc672d26b69f83f6aa31c98c6d6237892f6bdc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0aa115483a049bb1a9b406d3d9fa1dda4dcb47cf50236301f5ea9acca4c21b20118a027462e384d60c0cb287be92a80b163dc924f58a93a0f5998d0f2e577f4c
|
|
7
|
+
data.tar.gz: 2f31c241a2283f353bf503eb54d89921643ec5fdc0ecb8166c31d68b5deb79fb26f68ea412155cc17dc5734bce9a85451bd798c600365428d5f389eabdc41346
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -46,11 +46,6 @@ gem 'oj'
|
|
|
46
46
|
|
|
47
47
|
See the Quickstart sections of the [Rails](pages/Rails.md) and [json](pages/JsonGem.md) docs.
|
|
48
48
|
|
|
49
|
-
## multi_json
|
|
50
|
-
|
|
51
|
-
Code which uses [multi_json](https://github.com/intridea/multi_json)
|
|
52
|
-
will automatically prefer Oj if it is installed.
|
|
53
|
-
|
|
54
49
|
## Support
|
|
55
50
|
|
|
56
51
|
[Get supported Oj with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-oj?utm_source=rubygems-oj&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security).
|
|
@@ -83,17 +78,6 @@ See [{file:CHANGELOG.md}](CHANGELOG.md) and [{file:RELEASE_NOTES.md}](RELEASE_NO
|
|
|
83
78
|
|
|
84
79
|
- *RubyGems* *repo*: https://rubygems.org/gems/oj
|
|
85
80
|
|
|
86
|
-
Follow [@peterohler on Twitter](http://twitter.com/peterohler) for announcements and news about the Oj gem.
|
|
87
|
-
|
|
88
|
-
#### Performance Comparisons
|
|
89
|
-
|
|
90
|
-
- [Oj Strict Mode Performance](http://www.ohler.com/dev/oj_misc/performance_strict.html) compares Oj strict mode parser performance to other JSON parsers.
|
|
91
|
-
|
|
92
|
-
- [Oj Compat Mode Performance](http://www.ohler.com/dev/oj_misc/performance_compat.html) compares Oj compat mode parser performance to other JSON parsers.
|
|
93
|
-
|
|
94
|
-
- [Oj Object Mode Performance](http://www.ohler.com/dev/oj_misc/performance_object.html) compares Oj object mode parser performance to other marshallers.
|
|
95
|
-
|
|
96
|
-
- [Oj Callback Performance](http://www.ohler.com/dev/oj_misc/performance_callback.html) compares Oj callback parser performance to other JSON parsers.
|
|
97
81
|
|
|
98
82
|
#### Links of Interest
|
|
99
83
|
|
data/ext/oj/dump.c
CHANGED
|
@@ -40,7 +40,7 @@ static size_t ascii_friendly_size(const uint8_t *str, size_t len);
|
|
|
40
40
|
static const char hex_chars[17] = "0123456789abcdef";
|
|
41
41
|
|
|
42
42
|
// JSON standard except newlines are no escaped
|
|
43
|
-
static char newline_friendly_chars[
|
|
43
|
+
static char newline_friendly_chars[257] = "\
|
|
44
44
|
66666666221622666666666666666666\
|
|
45
45
|
11211111111111111111111111111111\
|
|
46
46
|
11111111111111111111111111112111\
|
|
@@ -51,7 +51,7 @@ static char newline_friendly_chars[256] = "\
|
|
|
51
51
|
11111111111111111111111111111111";
|
|
52
52
|
|
|
53
53
|
// JSON standard
|
|
54
|
-
static char hibit_friendly_chars[
|
|
54
|
+
static char hibit_friendly_chars[257] = "\
|
|
55
55
|
66666666222622666666666666666666\
|
|
56
56
|
11211111111111111111111111111111\
|
|
57
57
|
11111111111111111111111111112111\
|
|
@@ -62,7 +62,7 @@ static char hibit_friendly_chars[256] = "\
|
|
|
62
62
|
11111111111111111111111111111111";
|
|
63
63
|
|
|
64
64
|
// JSON standard but escape forward slashes `/`
|
|
65
|
-
static char slash_friendly_chars[
|
|
65
|
+
static char slash_friendly_chars[257] = "\
|
|
66
66
|
66666666222622666666666666666666\
|
|
67
67
|
11211111111111121111111111111111\
|
|
68
68
|
11111111111111111111111111112111\
|
|
@@ -74,7 +74,7 @@ static char slash_friendly_chars[256] = "\
|
|
|
74
74
|
|
|
75
75
|
// High bit set characters are always encoded as unicode. Worse case is 3
|
|
76
76
|
// bytes per character in the output. That makes this conservative.
|
|
77
|
-
static char ascii_friendly_chars[
|
|
77
|
+
static char ascii_friendly_chars[257] = "\
|
|
78
78
|
66666666222622666666666666666666\
|
|
79
79
|
11211111111111111111111111111111\
|
|
80
80
|
11111111111111111111111111112111\
|
|
@@ -85,7 +85,7 @@ static char ascii_friendly_chars[256] = "\
|
|
|
85
85
|
33333333333333333333333333333333";
|
|
86
86
|
|
|
87
87
|
// XSS safe mode
|
|
88
|
-
static char xss_friendly_chars[
|
|
88
|
+
static char xss_friendly_chars[257] = "\
|
|
89
89
|
66666666222622666666666666666666\
|
|
90
90
|
11211161111111121111111111116161\
|
|
91
91
|
11111111111111111111111111112111\
|
|
@@ -96,7 +96,7 @@ static char xss_friendly_chars[256] = "\
|
|
|
96
96
|
33333333333333333333333333333333";
|
|
97
97
|
|
|
98
98
|
// JSON XSS combo
|
|
99
|
-
static char hixss_friendly_chars[
|
|
99
|
+
static char hixss_friendly_chars[257] = "\
|
|
100
100
|
66666666222622666666666666666666\
|
|
101
101
|
11211111111111111111111111111111\
|
|
102
102
|
11111111111111111111111111112111\
|
|
@@ -107,7 +107,7 @@ static char hixss_friendly_chars[256] = "\
|
|
|
107
107
|
11611111111111111111111111111111";
|
|
108
108
|
|
|
109
109
|
// Rails XSS combo
|
|
110
|
-
static char rails_xss_friendly_chars[
|
|
110
|
+
static char rails_xss_friendly_chars[257] = "\
|
|
111
111
|
66666666222622666666666666666666\
|
|
112
112
|
11211161111111111111111111116161\
|
|
113
113
|
11111111111111111111111111112111\
|
|
@@ -118,7 +118,7 @@ static char rails_xss_friendly_chars[256] = "\
|
|
|
118
118
|
11611111111111111111111111111111";
|
|
119
119
|
|
|
120
120
|
// Rails HTML non-escape
|
|
121
|
-
static char rails_friendly_chars[
|
|
121
|
+
static char rails_friendly_chars[257] = "\
|
|
122
122
|
66666666222622666666666666666666\
|
|
123
123
|
11211111111111111111111111111111\
|
|
124
124
|
11111111111111111111111111112111\
|
data/ext/oj/fast.c
CHANGED
|
@@ -84,17 +84,6 @@ static void each_value(Doc doc, Leaf leaf);
|
|
|
84
84
|
|
|
85
85
|
VALUE oj_doc_class = Qundef;
|
|
86
86
|
|
|
87
|
-
// This is only for CentOS 5.4 with Ruby 1.9.3-p0.
|
|
88
|
-
#ifndef HAVE_STPCPY
|
|
89
|
-
char *stpcpy(char *dest, const char *src) {
|
|
90
|
-
size_t cnt = strlen(src);
|
|
91
|
-
|
|
92
|
-
strcpy(dest, src);
|
|
93
|
-
|
|
94
|
-
return dest + cnt;
|
|
95
|
-
}
|
|
96
|
-
#endif
|
|
97
|
-
|
|
98
87
|
inline static void next_non_white(ParseInfo pi) {
|
|
99
88
|
for (; 1; pi->s++) {
|
|
100
89
|
switch (*pi->s) {
|
|
@@ -246,6 +235,19 @@ static void skip_comment(ParseInfo pi) {
|
|
|
246
235
|
#define NUM_MAX (FIXNUM_MAX >> 8)
|
|
247
236
|
#endif
|
|
248
237
|
|
|
238
|
+
static void validate_integer_size(size_t limit, char *head, char *tail) {
|
|
239
|
+
size_t total = (size_t)(tail - head);
|
|
240
|
+
bool has_sign = (head[0] == '-' || head[0] == '+');
|
|
241
|
+
size_t digit_count = total - (has_sign ? 1 : 0);
|
|
242
|
+
|
|
243
|
+
if (digit_count > limit) {
|
|
244
|
+
rb_raise(oj_parse_error_class,
|
|
245
|
+
"integer exceeds :max_integer_digits (%lu > %lu)",
|
|
246
|
+
(unsigned long)digit_count,
|
|
247
|
+
(unsigned long)limit);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
249
251
|
static void leaf_fixnum_value(Leaf leaf) {
|
|
250
252
|
char *s = leaf->str;
|
|
251
253
|
int64_t n = 0;
|
|
@@ -265,7 +267,12 @@ static void leaf_fixnum_value(Leaf leaf) {
|
|
|
265
267
|
}
|
|
266
268
|
}
|
|
267
269
|
if (big) {
|
|
268
|
-
|
|
270
|
+
size_t limit = oj_default_options.max_integer_digits;
|
|
271
|
+
char c = *s;
|
|
272
|
+
|
|
273
|
+
if (0 < limit) {
|
|
274
|
+
validate_integer_size(limit, leaf->str, s);
|
|
275
|
+
}
|
|
269
276
|
|
|
270
277
|
*s = '\0';
|
|
271
278
|
leaf->value = rb_cstr_to_inum(leaf->str, 10, 0);
|
data/ext/oj/mimic_json.c
CHANGED
data/ext/oj/oj.c
CHANGED
|
@@ -122,6 +122,7 @@ static VALUE empty_string_sym;
|
|
|
122
122
|
static VALUE escape_mode_sym;
|
|
123
123
|
static VALUE except_sym;
|
|
124
124
|
static VALUE integer_range_sym;
|
|
125
|
+
static VALUE max_integer_digits_sym;
|
|
125
126
|
static VALUE fast_sym;
|
|
126
127
|
static VALUE float_prec_sym;
|
|
127
128
|
static VALUE float_format_sym;
|
|
@@ -206,6 +207,7 @@ struct _options oj_default_options = {
|
|
|
206
207
|
0, // cache_str
|
|
207
208
|
0, // int_range_min
|
|
208
209
|
0, // int_range_max
|
|
210
|
+
0, // max_integer_digits
|
|
209
211
|
oj_json_class, // create_id
|
|
210
212
|
10, // create_id_len
|
|
211
213
|
9, // sec_prec
|
|
@@ -334,6 +336,11 @@ static VALUE only_array_from_string(const char *str) {
|
|
|
334
336
|
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less
|
|
335
337
|
* than this are cached)
|
|
336
338
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
|
339
|
+
* - *:max_integer_digits* [_Fixnum_] Maximum number of decimal digits allowed in a
|
|
340
|
+
* parsed integer. When the limit is exceeded a parse error is raised. 0 (the
|
|
341
|
+
* default) disables the limit. Setting a reasonable limit is recommended when
|
|
342
|
+
* parsing untrusted input to mitigate CPU-DoS attacks. Only applies to the
|
|
343
|
+
* legacy parsers (Oj.load, Oj::Doc, JSON.parse mimic); Oj::Parser is unaffected.
|
|
337
344
|
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false
|
|
338
345
|
* (trace is off)
|
|
339
346
|
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default
|
|
@@ -448,6 +455,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
|
448
455
|
} else {
|
|
449
456
|
rb_hash_aset(opts, integer_range_sym, Qnil);
|
|
450
457
|
}
|
|
458
|
+
rb_hash_aset(opts, max_integer_digits_sym, LONG2NUM((long)oj_default_options.max_integer_digits));
|
|
451
459
|
switch (oj_default_options.escape_mode) {
|
|
452
460
|
case NLEsc: rb_hash_aset(opts, escape_mode_sym, newline_sym); break;
|
|
453
461
|
case JSONEsc: rb_hash_aset(opts, escape_mode_sym, json_sym); break;
|
|
@@ -591,6 +599,8 @@ static VALUE get_def_opts(VALUE self) {
|
|
|
591
599
|
* - *:cache_keys* [_Boolean_] if true then hash keys are cached
|
|
592
600
|
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
|
|
593
601
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
|
602
|
+
* - *:max_integer_digits* [_Fixnum_] Maximum decimal digits in a parsed integer
|
|
603
|
+
* (0 = unlimited). Use to mitigate CPU-DoS via huge integer values in JSON.
|
|
594
604
|
* - *:trace* [_Boolean_] turn trace on or off.
|
|
595
605
|
* - *:safe* [_Boolean_] turn safe mimic on or off.
|
|
596
606
|
*/
|
|
@@ -1071,6 +1081,20 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
|
1071
1081
|
} else if (Qfalse != v) {
|
|
1072
1082
|
rb_raise(rb_eArgError, ":integer_range must be a range of Fixnum.");
|
|
1073
1083
|
}
|
|
1084
|
+
} else if (max_integer_digits_sym == k) {
|
|
1085
|
+
if (Qnil == v || Qfalse == v) {
|
|
1086
|
+
copts->max_integer_digits = 0;
|
|
1087
|
+
} else if (T_FIXNUM == rb_type(v)) {
|
|
1088
|
+
long n = FIX2LONG(v);
|
|
1089
|
+
|
|
1090
|
+
if (n < 0) {
|
|
1091
|
+
rb_raise(rb_eArgError, ":max_integer_digits must be >= 0.");
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
copts->max_integer_digits = (size_t)n;
|
|
1095
|
+
} else {
|
|
1096
|
+
rb_raise(rb_eArgError, ":max_integer_digits must be a non-negative Integer.");
|
|
1097
|
+
}
|
|
1074
1098
|
} else if (symbol_keys_sym == k || oj_symbolize_names_sym == k) {
|
|
1075
1099
|
if (Qnil == v) {
|
|
1076
1100
|
return ST_CONTINUE;
|
|
@@ -2153,6 +2177,8 @@ void Init_oj(void) {
|
|
|
2153
2177
|
rb_gc_register_address(&escape_mode_sym);
|
|
2154
2178
|
integer_range_sym = ID2SYM(rb_intern("integer_range"));
|
|
2155
2179
|
rb_gc_register_address(&integer_range_sym);
|
|
2180
|
+
max_integer_digits_sym = ID2SYM(rb_intern("max_integer_digits"));
|
|
2181
|
+
rb_gc_register_address(&max_integer_digits_sym);
|
|
2156
2182
|
fast_sym = ID2SYM(rb_intern("fast"));
|
|
2157
2183
|
rb_gc_register_address(&fast_sym);
|
|
2158
2184
|
float_format_sym = ID2SYM(rb_intern("float_format"));
|
data/ext/oj/oj.h
CHANGED
|
@@ -124,43 +124,44 @@ typedef struct _dumpOpts {
|
|
|
124
124
|
} *DumpOpts;
|
|
125
125
|
|
|
126
126
|
typedef struct _options {
|
|
127
|
-
int indent;
|
|
128
|
-
char circular;
|
|
129
|
-
char auto_define;
|
|
130
|
-
char sym_key;
|
|
131
|
-
char escape_mode;
|
|
132
|
-
char mode;
|
|
133
|
-
char class_cache;
|
|
134
|
-
char time_format;
|
|
135
|
-
char bigdec_as_num;
|
|
136
|
-
char bigdec_load;
|
|
137
|
-
char compat_bigdec;
|
|
138
|
-
char to_hash;
|
|
139
|
-
char to_json;
|
|
140
|
-
char as_json;
|
|
141
|
-
char raw_json;
|
|
142
|
-
char nilnil;
|
|
143
|
-
char empty_string;
|
|
144
|
-
char allow_gc;
|
|
145
|
-
char quirks_mode;
|
|
146
|
-
char allow_invalid;
|
|
147
|
-
char create_ok;
|
|
148
|
-
char allow_nan;
|
|
149
|
-
char trace;
|
|
150
|
-
char safe;
|
|
151
|
-
char sec_prec_set;
|
|
152
|
-
char ignore_under;
|
|
153
|
-
char cache_keys;
|
|
154
|
-
char cache_str;
|
|
155
|
-
int64_t int_range_min;
|
|
156
|
-
int64_t int_range_max;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
char
|
|
162
|
-
|
|
163
|
-
VALUE
|
|
127
|
+
int indent; // indention for dump, default 2
|
|
128
|
+
char circular; // YesNo
|
|
129
|
+
char auto_define; // YesNo
|
|
130
|
+
char sym_key; // YesNo
|
|
131
|
+
char escape_mode; // Escape_Mode
|
|
132
|
+
char mode; // Mode
|
|
133
|
+
char class_cache; // YesNo
|
|
134
|
+
char time_format; // TimeFormat
|
|
135
|
+
char bigdec_as_num; // YesNo
|
|
136
|
+
char bigdec_load; // BigLoad
|
|
137
|
+
char compat_bigdec; // boolean (0 or 1)
|
|
138
|
+
char to_hash; // YesNo
|
|
139
|
+
char to_json; // YesNo
|
|
140
|
+
char as_json; // YesNo
|
|
141
|
+
char raw_json; // YesNo
|
|
142
|
+
char nilnil; // YesNo
|
|
143
|
+
char empty_string; // YesNo
|
|
144
|
+
char allow_gc; // allow GC during parse
|
|
145
|
+
char quirks_mode; // allow single JSON values instead of documents
|
|
146
|
+
char allow_invalid; // YesNo - allow invalid unicode
|
|
147
|
+
char create_ok; // YesNo allow create_id
|
|
148
|
+
char allow_nan; // YesNo for parsing only
|
|
149
|
+
char trace; // YesNo
|
|
150
|
+
char safe; // YesNo
|
|
151
|
+
char sec_prec_set; // boolean (0 or 1)
|
|
152
|
+
char ignore_under; // YesNo - ignore attrs starting with _ if true in object and custom modes
|
|
153
|
+
char cache_keys; // YesNo
|
|
154
|
+
char cache_str; // string short than or equal to this are cache
|
|
155
|
+
int64_t int_range_min; // dump numbers below as string
|
|
156
|
+
int64_t int_range_max; // dump numbers above as string
|
|
157
|
+
size_t max_integer_digits; // 0 = unlimited; max decimal digits for parsed integers
|
|
158
|
+
const char *create_id; // 0 or string
|
|
159
|
+
size_t create_id_len; // length of create_id
|
|
160
|
+
int sec_prec; // second precision when dumping time
|
|
161
|
+
char float_prec; // float precision, linked to float_fmt
|
|
162
|
+
char float_fmt[7]; // float format for dumping, if empty use Ruby
|
|
163
|
+
VALUE hash_class; // class to use in place of Hash on load
|
|
164
|
+
VALUE array_class; // class to use in place of Array on load
|
|
164
165
|
struct _dumpOpts dump_opts;
|
|
165
166
|
struct _rxClass str_rx;
|
|
166
167
|
VALUE *ignore; // Qnil terminated array of classes or NULL
|
data/ext/oj/parse.c
CHANGED
|
@@ -971,6 +971,20 @@ static long double exp_plus[] = {
|
|
|
971
971
|
1.0e39, 1.0e40, 1.0e41, 1.0e42, 1.0e43, 1.0e44, 1.0e45, 1.0e46, 1.0e47, 1.0e48, 1.0e49,
|
|
972
972
|
};
|
|
973
973
|
|
|
974
|
+
static void validate_integer_size(size_t limit, NumInfo ni) {
|
|
975
|
+
size_t digit_count = ni->len - (ni->neg ? 1 : 0);
|
|
976
|
+
|
|
977
|
+
if (digit_count > limit) {
|
|
978
|
+
oj_set_error_at(ni->pi,
|
|
979
|
+
(Qnil != ni->pi->err_class) ? ni->pi->err_class : oj_parse_error_class,
|
|
980
|
+
__FILE__,
|
|
981
|
+
__LINE__,
|
|
982
|
+
"integer exceeds :max_integer_digits (%lu > %lu)",
|
|
983
|
+
(unsigned long)digit_count,
|
|
984
|
+
(unsigned long)limit);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
974
988
|
VALUE
|
|
975
989
|
oj_num_as_value(NumInfo ni) {
|
|
976
990
|
VALUE rnum = Qnil;
|
|
@@ -984,6 +998,12 @@ oj_num_as_value(NumInfo ni) {
|
|
|
984
998
|
} else if (ni->nan) {
|
|
985
999
|
rnum = rb_float_new(0.0 / 0.0);
|
|
986
1000
|
} else if (1 == ni->div && 0 == ni->exp && !ni->has_exp) { // fixnum
|
|
1001
|
+
size_t limit = (NULL != ni->pi) ? ni->pi->options.max_integer_digits : 0;
|
|
1002
|
+
|
|
1003
|
+
if (0 < limit) {
|
|
1004
|
+
validate_integer_size(limit, ni);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
987
1007
|
if (ni->big) {
|
|
988
1008
|
if (256 > ni->len) {
|
|
989
1009
|
char buf[256];
|
data/ext/oj/parser.c
CHANGED
|
@@ -75,7 +75,7 @@ enum {
|
|
|
75
75
|
|
|
76
76
|
/*
|
|
77
77
|
0123456789abcdef0123456789abcdef */
|
|
78
|
-
static const char value_map[
|
|
78
|
+
static const char value_map[258] = "\
|
|
79
79
|
X........ab..a..................\
|
|
80
80
|
a.i..........f..ghhhhhhhhh......\
|
|
81
81
|
...........................k.m..\
|
|
@@ -85,7 +85,7 @@ a.i..........f..ghhhhhhhhh......\
|
|
|
85
85
|
................................\
|
|
86
86
|
................................v";
|
|
87
87
|
|
|
88
|
-
static const char null_map[
|
|
88
|
+
static const char null_map[258] = "\
|
|
89
89
|
................................\
|
|
90
90
|
............o...................\
|
|
91
91
|
................................\
|
|
@@ -95,7 +95,7 @@ static const char null_map[257] = "\
|
|
|
95
95
|
................................\
|
|
96
96
|
................................N";
|
|
97
97
|
|
|
98
|
-
static const char true_map[
|
|
98
|
+
static const char true_map[258] = "\
|
|
99
99
|
................................\
|
|
100
100
|
............o...................\
|
|
101
101
|
................................\
|
|
@@ -105,7 +105,7 @@ static const char true_map[257] = "\
|
|
|
105
105
|
................................\
|
|
106
106
|
................................T";
|
|
107
107
|
|
|
108
|
-
static const char false_map[
|
|
108
|
+
static const char false_map[258] = "\
|
|
109
109
|
................................\
|
|
110
110
|
............o...................\
|
|
111
111
|
................................\
|
|
@@ -115,7 +115,7 @@ static const char false_map[257] = "\
|
|
|
115
115
|
................................\
|
|
116
116
|
................................F";
|
|
117
117
|
|
|
118
|
-
static const char comma_map[
|
|
118
|
+
static const char comma_map[258] = "\
|
|
119
119
|
.........ab..a..................\
|
|
120
120
|
a.i..........f..ghhhhhhhhh......\
|
|
121
121
|
...........................k....\
|
|
@@ -125,7 +125,7 @@ a.i..........f..ghhhhhhhhh......\
|
|
|
125
125
|
................................\
|
|
126
126
|
................................,";
|
|
127
127
|
|
|
128
|
-
static const char after_map[
|
|
128
|
+
static const char after_map[258] = "\
|
|
129
129
|
X........ab..a..................\
|
|
130
130
|
a...........o...................\
|
|
131
131
|
.............................m..\
|
|
@@ -135,7 +135,7 @@ a...........o...................\
|
|
|
135
135
|
................................\
|
|
136
136
|
................................a";
|
|
137
137
|
|
|
138
|
-
static const char key1_map[
|
|
138
|
+
static const char key1_map[258] = "\
|
|
139
139
|
.........ab..a..................\
|
|
140
140
|
a.p.............................\
|
|
141
141
|
................................\
|
|
@@ -145,7 +145,7 @@ a.p.............................\
|
|
|
145
145
|
................................\
|
|
146
146
|
................................K";
|
|
147
147
|
|
|
148
|
-
static const char key_map[
|
|
148
|
+
static const char key_map[258] = "\
|
|
149
149
|
.........ab..a..................\
|
|
150
150
|
a.p.............................\
|
|
151
151
|
................................\
|
|
@@ -155,7 +155,7 @@ a.p.............................\
|
|
|
155
155
|
................................\
|
|
156
156
|
................................k";
|
|
157
157
|
|
|
158
|
-
static const char colon_map[
|
|
158
|
+
static const char colon_map[258] = "\
|
|
159
159
|
.........ab..a..................\
|
|
160
160
|
a.........................q.....\
|
|
161
161
|
................................\
|
|
@@ -165,7 +165,7 @@ a.........................q.....\
|
|
|
165
165
|
................................\
|
|
166
166
|
................................:";
|
|
167
167
|
|
|
168
|
-
static const char neg_map[
|
|
168
|
+
static const char neg_map[258] = "\
|
|
169
169
|
................................\
|
|
170
170
|
................O---------......\
|
|
171
171
|
................................\
|
|
@@ -175,7 +175,7 @@ static const char neg_map[257] = "\
|
|
|
175
175
|
................................\
|
|
176
176
|
................................-";
|
|
177
177
|
|
|
178
|
-
static const char zero_map[
|
|
178
|
+
static const char zero_map[258] = "\
|
|
179
179
|
.........rs..r..................\
|
|
180
180
|
r...........u.t.................\
|
|
181
181
|
.............................H..\
|
|
@@ -185,7 +185,7 @@ r...........u.t.................\
|
|
|
185
185
|
................................\
|
|
186
186
|
................................0";
|
|
187
187
|
|
|
188
|
-
static const char digit_map[
|
|
188
|
+
static const char digit_map[258] = "\
|
|
189
189
|
.........rs..r..................\
|
|
190
190
|
r...........u.t.NNNNNNNNNN......\
|
|
191
191
|
.....w.......................H..\
|
|
@@ -195,7 +195,7 @@ r...........u.t.NNNNNNNNNN......\
|
|
|
195
195
|
................................\
|
|
196
196
|
................................d";
|
|
197
197
|
|
|
198
|
-
static const char dot_map[
|
|
198
|
+
static const char dot_map[258] = "\
|
|
199
199
|
................................\
|
|
200
200
|
................vvvvvvvvvv......\
|
|
201
201
|
................................\
|
|
@@ -205,7 +205,7 @@ static const char dot_map[257] = "\
|
|
|
205
205
|
................................\
|
|
206
206
|
.................................";
|
|
207
207
|
|
|
208
|
-
static const char frac_map[
|
|
208
|
+
static const char frac_map[258] = "\
|
|
209
209
|
.........rs..r..................\
|
|
210
210
|
r...........u...vvvvvvvvvv......\
|
|
211
211
|
.....w.......................H..\
|
|
@@ -215,7 +215,7 @@ r...........u...vvvvvvvvvv......\
|
|
|
215
215
|
................................\
|
|
216
216
|
................................f";
|
|
217
217
|
|
|
218
|
-
static const char exp_sign_map[
|
|
218
|
+
static const char exp_sign_map[258] = "\
|
|
219
219
|
................................\
|
|
220
220
|
...........x.x..yyyyyyyyyy......\
|
|
221
221
|
................................\
|
|
@@ -225,7 +225,7 @@ static const char exp_sign_map[257] = "\
|
|
|
225
225
|
................................\
|
|
226
226
|
................................x";
|
|
227
227
|
|
|
228
|
-
static const char exp_zero_map[
|
|
228
|
+
static const char exp_zero_map[258] = "\
|
|
229
229
|
................................\
|
|
230
230
|
................yyyyyyyyyy......\
|
|
231
231
|
................................\
|
|
@@ -235,7 +235,7 @@ static const char exp_zero_map[257] = "\
|
|
|
235
235
|
................................\
|
|
236
236
|
................................z";
|
|
237
237
|
|
|
238
|
-
static const char exp_map[
|
|
238
|
+
static const char exp_map[258] = "\
|
|
239
239
|
.........rs..r..................\
|
|
240
240
|
r...........u...yyyyyyyyyy......\
|
|
241
241
|
.............................H..\
|
|
@@ -245,7 +245,7 @@ r...........u...yyyyyyyyyy......\
|
|
|
245
245
|
................................\
|
|
246
246
|
................................X";
|
|
247
247
|
|
|
248
|
-
static const char big_digit_map[
|
|
248
|
+
static const char big_digit_map[258] = "\
|
|
249
249
|
.........rs..r..................\
|
|
250
250
|
r...........u.D.CCCCCCCCCC......\
|
|
251
251
|
.....J.......................H..\
|
|
@@ -255,7 +255,7 @@ r...........u.D.CCCCCCCCCC......\
|
|
|
255
255
|
................................\
|
|
256
256
|
................................D";
|
|
257
257
|
|
|
258
|
-
static const char big_dot_map[
|
|
258
|
+
static const char big_dot_map[258] = "\
|
|
259
259
|
................................\
|
|
260
260
|
................IIIIIIIIII......\
|
|
261
261
|
................................\
|
|
@@ -265,7 +265,7 @@ static const char big_dot_map[257] = "\
|
|
|
265
265
|
................................\
|
|
266
266
|
................................o";
|
|
267
267
|
|
|
268
|
-
static const char big_frac_map[
|
|
268
|
+
static const char big_frac_map[258] = "\
|
|
269
269
|
.........rs..r..................\
|
|
270
270
|
r...........u...IIIIIIIIII......\
|
|
271
271
|
.....J.......................H..\
|
|
@@ -275,7 +275,7 @@ r...........u...IIIIIIIIII......\
|
|
|
275
275
|
................................\
|
|
276
276
|
................................g";
|
|
277
277
|
|
|
278
|
-
static const char big_exp_sign_map[
|
|
278
|
+
static const char big_exp_sign_map[258] = "\
|
|
279
279
|
................................\
|
|
280
280
|
...........K.K..LLLLLLLLLL......\
|
|
281
281
|
................................\
|
|
@@ -285,7 +285,7 @@ static const char big_exp_sign_map[257] = "\
|
|
|
285
285
|
................................\
|
|
286
286
|
................................B";
|
|
287
287
|
|
|
288
|
-
static const char big_exp_zero_map[
|
|
288
|
+
static const char big_exp_zero_map[258] = "\
|
|
289
289
|
................................\
|
|
290
290
|
................LLLLLLLLLL......\
|
|
291
291
|
................................\
|
|
@@ -295,7 +295,7 @@ static const char big_exp_zero_map[257] = "\
|
|
|
295
295
|
................................\
|
|
296
296
|
................................Z";
|
|
297
297
|
|
|
298
|
-
static const char big_exp_map[
|
|
298
|
+
static const char big_exp_map[258] = "\
|
|
299
299
|
.........rs..r..................\
|
|
300
300
|
r...........u...LLLLLLLLLL......\
|
|
301
301
|
.............................H..\
|
|
@@ -305,7 +305,7 @@ r...........u...LLLLLLLLLL......\
|
|
|
305
305
|
................................\
|
|
306
306
|
................................Y";
|
|
307
307
|
|
|
308
|
-
static const char string_map[
|
|
308
|
+
static const char string_map[258] = "\
|
|
309
309
|
................................\
|
|
310
310
|
RRzRRRRRRRRRRRRRRRRRRRRRRRRRRRRR\
|
|
311
311
|
RRRRRRRRRRRRRRRRRRRRRRRRRRRRARRR\
|
|
@@ -315,7 +315,7 @@ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR\
|
|
|
315
315
|
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\
|
|
316
316
|
PPPPPPPPPPPPPPPPQQQQQQQQ........s";
|
|
317
317
|
|
|
318
|
-
static const char esc_map[
|
|
318
|
+
static const char esc_map[258] = "\
|
|
319
319
|
................................\
|
|
320
320
|
..B............B................\
|
|
321
321
|
............................B...\
|
|
@@ -325,7 +325,7 @@ static const char esc_map[257] = "\
|
|
|
325
325
|
................................\
|
|
326
326
|
................................~";
|
|
327
327
|
|
|
328
|
-
static const char esc_byte_map[
|
|
328
|
+
static const char esc_byte_map[258] = "\
|
|
329
329
|
................................\
|
|
330
330
|
..\"............/................\
|
|
331
331
|
............................\\...\
|
|
@@ -335,7 +335,7 @@ static const char esc_byte_map[257] = "\
|
|
|
335
335
|
................................\
|
|
336
336
|
................................b";
|
|
337
337
|
|
|
338
|
-
static const char u_map[
|
|
338
|
+
static const char u_map[258] = "\
|
|
339
339
|
................................\
|
|
340
340
|
................EEEEEEEEEE......\
|
|
341
341
|
.EEEEEE.........................\
|
|
@@ -345,7 +345,7 @@ static const char u_map[257] = "\
|
|
|
345
345
|
................................\
|
|
346
346
|
................................u";
|
|
347
347
|
|
|
348
|
-
static const char utf_map[
|
|
348
|
+
static const char utf_map[258] = "\
|
|
349
349
|
................................\
|
|
350
350
|
................................\
|
|
351
351
|
................................\
|
|
@@ -355,7 +355,7 @@ SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\
|
|
|
355
355
|
................................\
|
|
356
356
|
................................8";
|
|
357
357
|
|
|
358
|
-
static const char space_map[
|
|
358
|
+
static const char space_map[258] = "\
|
|
359
359
|
.........ab..a..................\
|
|
360
360
|
a...............................\
|
|
361
361
|
................................\
|
|
@@ -365,7 +365,7 @@ a...............................\
|
|
|
365
365
|
................................\
|
|
366
366
|
................................S";
|
|
367
367
|
|
|
368
|
-
static const char trail_map[
|
|
368
|
+
static const char trail_map[258] = "\
|
|
369
369
|
.........ab..a..................\
|
|
370
370
|
a...............................\
|
|
371
371
|
................................\
|
|
@@ -375,7 +375,7 @@ a...............................\
|
|
|
375
375
|
................................\
|
|
376
376
|
................................R";
|
|
377
377
|
|
|
378
|
-
static const byte hex_map[
|
|
378
|
+
static const byte hex_map[257] = "\
|
|
379
379
|
................................\
|
|
380
380
|
................\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09......\
|
|
381
381
|
.\x0a\x0b\x0c\x0d\x0e\x0f.........................\
|
|
@@ -594,7 +594,7 @@ static void big_change(ojParser p) {
|
|
|
594
594
|
}
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
-
static void parse(ojParser p, const byte *json) {
|
|
597
|
+
static void parse(ojParser p, const byte *json, bool more) {
|
|
598
598
|
const byte *start;
|
|
599
599
|
const byte *b = json;
|
|
600
600
|
int i;
|
|
@@ -635,7 +635,7 @@ static void parse(ojParser p, const byte *json) {
|
|
|
635
635
|
if ('"' == *b) {
|
|
636
636
|
p->map = colon_map;
|
|
637
637
|
break;
|
|
638
|
-
} else if ('\0' == *b) {
|
|
638
|
+
} else if ('\0' == *b && !more) {
|
|
639
639
|
parse_error(p, "quoted string not terminated");
|
|
640
640
|
break;
|
|
641
641
|
}
|
|
@@ -662,7 +662,7 @@ static void parse(ojParser p, const byte *json) {
|
|
|
662
662
|
p->funcs[p->stack[p->depth]].add_str(p);
|
|
663
663
|
p->map = (0 == p->depth) ? value_map : after_map;
|
|
664
664
|
break;
|
|
665
|
-
} else if ('\0' == *b) {
|
|
665
|
+
} else if ('\0' == *b && !more) {
|
|
666
666
|
parse_error(p, "quoted string not terminated");
|
|
667
667
|
break;
|
|
668
668
|
}
|
|
@@ -1378,7 +1378,6 @@ static void validate_non_primitives_are_complete(ojParser p) {
|
|
|
1378
1378
|
if (0 >= p->depth) {
|
|
1379
1379
|
return;
|
|
1380
1380
|
}
|
|
1381
|
-
|
|
1382
1381
|
if (OBJECT_FUN == p->stack[p->depth]) {
|
|
1383
1382
|
parse_error(p, "Object is not closed");
|
|
1384
1383
|
} else {
|
|
@@ -1406,7 +1405,7 @@ static VALUE parser_parse(VALUE self, VALUE json) {
|
|
|
1406
1405
|
|
|
1407
1406
|
parser_reset(p);
|
|
1408
1407
|
p->start(p);
|
|
1409
|
-
parse(p, ptr);
|
|
1408
|
+
parse(p, ptr, false);
|
|
1410
1409
|
|
|
1411
1410
|
validate_document_end(p);
|
|
1412
1411
|
|
|
@@ -1428,7 +1427,7 @@ static VALUE load(VALUE self) {
|
|
|
1428
1427
|
while (true) {
|
|
1429
1428
|
rb_funcall(p->reader, oj_readpartial_id, 2, INT2NUM(16385), rbuf);
|
|
1430
1429
|
if (0 < RSTRING_LEN(rbuf)) {
|
|
1431
|
-
parse(p, (byte *)StringValuePtr(rbuf));
|
|
1430
|
+
parse(p, (byte *)StringValuePtr(rbuf), true);
|
|
1432
1431
|
}
|
|
1433
1432
|
if (Qtrue == rb_funcall(p->reader, oj_eofq_id, 0)) {
|
|
1434
1433
|
if (0 < p->depth) {
|
|
@@ -1498,7 +1497,7 @@ static VALUE parser_file(VALUE self, VALUE filename) {
|
|
|
1498
1497
|
while (true) {
|
|
1499
1498
|
if (0 < (rsize = read(fd, buf, size))) {
|
|
1500
1499
|
buf[rsize] = '\0';
|
|
1501
|
-
parse(p, buf);
|
|
1500
|
+
parse(p, buf, true);
|
|
1502
1501
|
}
|
|
1503
1502
|
if (rsize <= 0) {
|
|
1504
1503
|
if (0 != rsize) {
|
data/ext/oj/sparse.c
CHANGED
|
@@ -399,6 +399,7 @@ static void read_num(ParseInfo pi) {
|
|
|
399
399
|
char c;
|
|
400
400
|
|
|
401
401
|
reader_protect(&pi->rd);
|
|
402
|
+
ni.pi = pi;
|
|
402
403
|
ni.i = 0;
|
|
403
404
|
ni.num = 0;
|
|
404
405
|
ni.div = 1;
|
|
@@ -549,6 +550,7 @@ static void read_nan(ParseInfo pi) {
|
|
|
549
550
|
struct _numInfo ni;
|
|
550
551
|
char c;
|
|
551
552
|
|
|
553
|
+
ni.pi = pi;
|
|
552
554
|
ni.str = pi->rd.str;
|
|
553
555
|
ni.i = 0;
|
|
554
556
|
ni.num = 0;
|
|
@@ -745,6 +747,7 @@ void oj_sparse2(ParseInfo pi) {
|
|
|
745
747
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "expected NaN");
|
|
746
748
|
return;
|
|
747
749
|
}
|
|
750
|
+
ni.pi = pi;
|
|
748
751
|
ni.str = pi->rd.str;
|
|
749
752
|
ni.i = 0;
|
|
750
753
|
ni.num = 0;
|
data/ext/oj/wab.c
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
|
|
20
20
|
#define OJ_INFINITY (1.0 / 0.0)
|
|
21
21
|
|
|
22
|
-
static char hex_chars[
|
|
22
|
+
static char hex_chars[257] = "\
|
|
23
23
|
................................\
|
|
24
24
|
................xxxxxxxxxx......\
|
|
25
25
|
.xxxxxx.........................\
|
data/lib/oj/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: oj
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.17.
|
|
4
|
+
version: 3.17.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Ohler
|
|
@@ -231,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
231
231
|
- !ruby/object:Gem::Version
|
|
232
232
|
version: '0'
|
|
233
233
|
requirements: []
|
|
234
|
-
rubygems_version:
|
|
234
|
+
rubygems_version: 4.0.6
|
|
235
235
|
specification_version: 4
|
|
236
236
|
summary: A fast JSON parser and serializer.
|
|
237
237
|
test_files: []
|