oj 3.3.6 → 3.3.7
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/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.
|