oj 3.3.6 → 3.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/oj/compat.c +22 -0
- data/ext/oj/dump.c +10 -1
- data/ext/oj/mimic_json.c +4 -3
- data/ext/oj/oj.h +1 -0
- data/ext/oj/parse.c +9 -2
- data/ext/oj/parse.h +18 -0
- data/ext/oj/sparse.c +6 -1
- data/lib/oj/version.rb +1 -1
- data/pages/Modes.md +1 -1
- data/pages/Options.md +15 -12
- data/test/json_gem/json_common_interface_test.rb +5 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4d5410c27e25a4075040fce057dafda891377af
|
4
|
+
data.tar.gz: f06d843cbecfc3c54eac85685be54fb9d0a2cafa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f5f28ef22ad9c2b60699458eb5a2e98c70a991989649b974b67c25109d31076a48244c4970aea3af4055d734f7e3c121ec9cdc1f73ed643d2a969c8895149f3
|
7
|
+
data.tar.gz: eee14c01cf62adabfcfe162997e74e7b31da61a5e2446495221446584e9bb39e8baaae20eff8a3245804c29a84812bb73f3a0f85d567deff9c6d90cc0f5f7e51
|
data/ext/oj/compat.c
CHANGED
@@ -217,6 +217,7 @@ oj_compat_parse(int argc, VALUE *argv, VALUE self) {
|
|
217
217
|
pi.max_depth = 0;
|
218
218
|
pi.options.allow_nan = Yes;
|
219
219
|
pi.options.nilnil = Yes;
|
220
|
+
pi.options.empty_string = No;
|
220
221
|
oj_set_compat_callbacks(&pi);
|
221
222
|
|
222
223
|
if (T_STRING == rb_type(*argv)) {
|
@@ -226,6 +227,27 @@ oj_compat_parse(int argc, VALUE *argv, VALUE self) {
|
|
226
227
|
}
|
227
228
|
}
|
228
229
|
|
230
|
+
VALUE
|
231
|
+
oj_compat_load(int argc, VALUE *argv, VALUE self) {
|
232
|
+
struct _ParseInfo pi;
|
233
|
+
|
234
|
+
parse_info_init(&pi);
|
235
|
+
pi.options = oj_default_options;
|
236
|
+
pi.handler = Qnil;
|
237
|
+
pi.err_class = Qnil;
|
238
|
+
pi.max_depth = 0;
|
239
|
+
pi.options.allow_nan = Yes;
|
240
|
+
pi.options.nilnil = Yes;
|
241
|
+
pi.options.empty_string = Yes;
|
242
|
+
oj_set_compat_callbacks(&pi);
|
243
|
+
|
244
|
+
if (T_STRING == rb_type(*argv)) {
|
245
|
+
return oj_pi_parse(argc, argv, &pi, 0, 0, false);
|
246
|
+
} else {
|
247
|
+
return oj_pi_sparse(argc, argv, &pi, 0);
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
229
251
|
VALUE
|
230
252
|
oj_compat_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
|
231
253
|
struct _ParseInfo pi;
|
data/ext/oj/dump.c
CHANGED
@@ -689,6 +689,7 @@ void
|
|
689
689
|
oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
690
690
|
size_t size;
|
691
691
|
char *cmap;
|
692
|
+
const char *orig = str;
|
692
693
|
|
693
694
|
switch (out->opts->escape_mode) {
|
694
695
|
case NLEsc:
|
@@ -817,7 +818,15 @@ oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
|
|
817
818
|
// 0x110xxxxx for 2 characters, 0x1110xxxx for 3, and 0x11110xxx for
|
818
819
|
// 4.
|
819
820
|
if (0 != (0x40 & c)) {
|
820
|
-
|
821
|
+
char buf[1024];
|
822
|
+
char *b = buf;
|
823
|
+
const char *s = orig;
|
824
|
+
|
825
|
+
for (; s < s + cnt; s++) {
|
826
|
+
b += sprintf(b, " %02x", *s);
|
827
|
+
}
|
828
|
+
*b = '\0';
|
829
|
+
rb_raise(oj_json_generator_error_class, "Partial character in string. %s", buf);
|
821
830
|
}
|
822
831
|
for (i = 1; i < (int)cnt && i < 4; i++) {
|
823
832
|
c = str[-1 - i];
|
data/ext/oj/mimic_json.c
CHANGED
@@ -317,7 +317,7 @@ mimic_load(int argc, VALUE *argv, VALUE self) {
|
|
317
317
|
VALUE obj;
|
318
318
|
VALUE p = Qnil;
|
319
319
|
|
320
|
-
obj =
|
320
|
+
obj = oj_compat_load(argc, argv, self);
|
321
321
|
if (2 <= argc) {
|
322
322
|
if (rb_cProc == rb_obj_class(argv[1])) {
|
323
323
|
p = argv[1];
|
@@ -491,7 +491,7 @@ mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
|
|
491
491
|
rb_scan_args(argc, argv, "11", NULL, &ropts);
|
492
492
|
parse_info_init(&pi);
|
493
493
|
oj_set_compat_callbacks(&pi);
|
494
|
-
|
494
|
+
|
495
495
|
pi.err_class = oj_json_parser_error_class;
|
496
496
|
//pi.err_class = Qnil;
|
497
497
|
|
@@ -678,7 +678,7 @@ static struct _Options mimic_object_to_json_options = {
|
|
678
678
|
No, // to_json
|
679
679
|
No, // as_json
|
680
680
|
No, // nilnil
|
681
|
-
|
681
|
+
No, // empty_string
|
682
682
|
Yes, // allow_gc
|
683
683
|
Yes, // quirks_mode
|
684
684
|
No, // allow_invalid
|
@@ -795,6 +795,7 @@ oj_mimic_json_methods(VALUE json) {
|
|
795
795
|
} else {
|
796
796
|
oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
|
797
797
|
}
|
798
|
+
printf("*** setting parse error to %lx %s\n", oj_json_parser_error_class, rb_class2name(oj_json_parser_error_class));
|
798
799
|
if (rb_const_defined_at(json, rb_intern("GeneratorError"))) {
|
799
800
|
oj_json_generator_error_class = rb_const_get(json, rb_intern("GeneratorError"));
|
800
801
|
} else {
|
data/ext/oj/oj.h
CHANGED
@@ -244,6 +244,7 @@ extern VALUE oj_sc_parse(int argc, VALUE *argv, VALUE self);
|
|
244
244
|
extern VALUE oj_strict_parse(int argc, VALUE *argv, VALUE self);
|
245
245
|
extern VALUE oj_strict_sparse(int argc, VALUE *argv, VALUE self);
|
246
246
|
extern VALUE oj_compat_parse(int argc, VALUE *argv, VALUE self);
|
247
|
+
extern VALUE oj_compat_load(int argc, VALUE *argv, VALUE self);
|
247
248
|
extern VALUE oj_object_parse(int argc, VALUE *argv, VALUE self);
|
248
249
|
extern VALUE oj_custom_parse(int argc, VALUE *argv, VALUE self);
|
249
250
|
extern VALUE oj_wab_parse(int argc, VALUE *argv, VALUE self);
|
data/ext/oj/parse.c
CHANGED
@@ -859,8 +859,10 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
859
859
|
pi->end = json + len;
|
860
860
|
free_json = 1;
|
861
861
|
} else if (T_STRING == rb_type(input)) {
|
862
|
-
if (
|
863
|
-
|
862
|
+
if (CompatMode == pi->options.mode) {
|
863
|
+
if (No == pi->options.nilnil && 0 == RSTRING_LEN(input)) {
|
864
|
+
rb_raise(oj_json_parser_error_class, "An empty string is not a valid JSON string.");
|
865
|
+
}
|
864
866
|
}
|
865
867
|
oj_pi_set_input_str(pi, &input);
|
866
868
|
} else if (Qnil == input) {
|
@@ -919,6 +921,11 @@ oj_pi_parse(int argc, VALUE *argv, ParseInfo pi, char *json, size_t len, int yie
|
|
919
921
|
// value stack (while it is in scope).
|
920
922
|
wrapped_stack = oj_stack_init(&pi->stack);
|
921
923
|
rb_protect(protect_parse, (VALUE)pi, &line);
|
924
|
+
if (Qundef == pi->stack.head->val && !empty_ok(&pi->options)) {
|
925
|
+
if (No == pi->options.nilnil || (CompatMode == pi->options.mode && 0 < pi->cur - pi->json)) {
|
926
|
+
oj_set_error_at(pi, oj_json_parser_error_class, __FILE__, __LINE__, "Empty input");
|
927
|
+
}
|
928
|
+
}
|
922
929
|
result = stack_head_val(&pi->stack);
|
923
930
|
DATA_PTR(wrapped_stack) = 0;
|
924
931
|
if (No == pi->options.allow_gc) {
|
data/ext/oj/parse.h
CHANGED
@@ -90,4 +90,22 @@ parse_info_init(ParseInfo pi) {
|
|
90
90
|
memset(pi, 0, sizeof(struct _ParseInfo));
|
91
91
|
}
|
92
92
|
|
93
|
+
static inline bool
|
94
|
+
empty_ok(Options options) {
|
95
|
+
switch (options->mode) {
|
96
|
+
case ObjectMode:
|
97
|
+
case WabMode:
|
98
|
+
return true;
|
99
|
+
case CompatMode:
|
100
|
+
case RailsMode:
|
101
|
+
return false;
|
102
|
+
case StrictMode:
|
103
|
+
case NullMode:
|
104
|
+
case CustomMode:
|
105
|
+
default:
|
106
|
+
break;
|
107
|
+
}
|
108
|
+
return Yes == options->empty_string;
|
109
|
+
}
|
110
|
+
|
93
111
|
#endif /* __OJ_PARSE_H__ */
|
data/ext/oj/sparse.c
CHANGED
@@ -826,6 +826,8 @@ oj_pi_sparse(int argc, VALUE *argv, ParseInfo pi, int fd) {
|
|
826
826
|
} else {
|
827
827
|
rb_raise(rb_eTypeError, "Nil is not a valid JSON source.");
|
828
828
|
}
|
829
|
+
} else if (CompatMode == pi->options.mode && T_STRING == rb_type(input) && No == pi->options.nilnil && 0 == RSTRING_LEN(input)) {
|
830
|
+
rb_raise(oj_json_parser_error_class, "An empty string is not a valid JSON string.");
|
829
831
|
}
|
830
832
|
if (rb_block_given_p()) {
|
831
833
|
pi->proc = Qnil;
|
@@ -845,10 +847,13 @@ oj_pi_sparse(int argc, VALUE *argv, ParseInfo pi, int fd) {
|
|
845
847
|
}
|
846
848
|
// GC can run at any time. When it runs any Object created by C will be
|
847
849
|
// freed. We protect against this by wrapping the value stack in a ruby
|
848
|
-
// data object and
|
850
|
+
// data object and providing a mark function for ruby objects on the
|
849
851
|
// value stack (while it is in scope).
|
850
852
|
wrapped_stack = oj_stack_init(&pi->stack);
|
851
853
|
rb_protect(protect_parse, (VALUE)pi, &line);
|
854
|
+
if (Qundef == pi->stack.head->val && !empty_ok(&pi->options)) {
|
855
|
+
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "Empty input");
|
856
|
+
}
|
852
857
|
result = stack_head_val(&pi->stack);
|
853
858
|
DATA_PTR(wrapped_stack) = 0;
|
854
859
|
if (No == pi->options.allow_gc) {
|
data/lib/oj/version.rb
CHANGED
data/pages/Modes.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Oj Modes
|
2
2
|
|
3
3
|
Oj uses modes to switch the load and dump behavior. Initially Oj supported on
|
4
|
-
the :object mode which uses a format that allows
|
4
|
+
the :object mode which uses a format that allows Ruby object encoding and
|
5
5
|
decoding in a manner that lets almost any Ruby object be encoded and decoded
|
6
6
|
without monkey patching the object classes. From that start other demands were
|
7
7
|
made the were best met by giving Oj multiple modes of operation. The current
|
data/pages/Options.md
CHANGED
@@ -91,18 +91,21 @@ specifying the class for an encoded object. The default is `json_create`.
|
|
91
91
|
|
92
92
|
### :empty_string [Boolean]
|
93
93
|
|
94
|
-
If true an empty input will not raise an Exception. The
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
94
|
+
If true an empty or all whitespace input will not raise an Exception. The
|
95
|
+
default_options will be honored for :null, :strict, and :custom modes. Ignored
|
96
|
+
for :custom and :wab. The :compat has a more complex set of rules. The JSON
|
97
|
+
gem compatibility is best described by examples.
|
98
|
+
|
99
|
+
```
|
100
|
+
JSON.parse('') => raise
|
101
|
+
JSON.parse(' ') => raise
|
102
|
+
JSON.load('') => nil
|
103
|
+
JSON.load('', nil, allow_blank: false) => raise
|
104
|
+
JSON.load('', nil, allow_blank: true) => nil
|
105
|
+
JSON.load(' ') => raise
|
106
|
+
JSON.load(' ', nil, allow_blank: false) => raise
|
107
|
+
JSON.load(' ', nil, allow_blank: true) => raise
|
108
|
+
```
|
106
109
|
|
107
110
|
### :escape_mode [Symbol]
|
108
111
|
|
@@ -112,6 +112,11 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
|
|
112
112
|
assert_equal nil, JSON.load(nil, nil, :allow_blank => true)
|
113
113
|
assert_raise(TypeError) { JSON.load(nil, nil, :allow_blank => false) }
|
114
114
|
assert_raise(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) }
|
115
|
+
# The next tests are added by Oj to catch additional cases.
|
116
|
+
assert_equal nil, JSON.load('', nil, :allow_blank => true)
|
117
|
+
assert_raise(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) }
|
118
|
+
assert_raise(JSON::ParserError) { JSON.load(' ', nil, :allow_blank => true) }
|
119
|
+
assert_raise(JSON::ParserError) { JSON.load(' ', nil, :allow_blank => false) }
|
115
120
|
end
|
116
121
|
|
117
122
|
def test_dump
|
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.3.
|
4
|
+
version: 3.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -260,7 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
260
|
version: '0'
|
261
261
|
requirements: []
|
262
262
|
rubyforge_project: oj
|
263
|
-
rubygems_version: 2.6.
|
263
|
+
rubygems_version: 2.6.11
|
264
264
|
signing_key:
|
265
265
|
specification_version: 4
|
266
266
|
summary: A fast JSON parser and serializer.
|