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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: deb93f1a098c0d7ed3cf11105c2b76ea98ab692a
4
- data.tar.gz: f7cf3c8f48c0d4329a01771837f13d09103bf37c
3
+ metadata.gz: f4d5410c27e25a4075040fce057dafda891377af
4
+ data.tar.gz: f06d843cbecfc3c54eac85685be54fb9d0a2cafa
5
5
  SHA512:
6
- metadata.gz: d0550705f9f2147b3e9ab45d6e96671050ec0b8f5b42338e9e8e277ea305e68d67407fdeffae673b330d827da657218d5c1a8e44fe4dbb889fd0922a88314c58
7
- data.tar.gz: 9b6337fc9ab58ff49868f069275cac7a8f427ecde5a40a31de78af97494c8aefef7cb23a5765f05c3be5cfcc37fa6e44b10af1d8960a8f4a94d3b4f7b4fe56b5
6
+ metadata.gz: 5f5f28ef22ad9c2b60699458eb5a2e98c70a991989649b974b67c25109d31076a48244c4970aea3af4055d734f7e3c121ec9cdc1f73ed643d2a969c8895149f3
7
+ data.tar.gz: eee14c01cf62adabfcfe162997e74e7b31da61a5e2446495221446584e9bb39e8baaae20eff8a3245804c29a84812bb73f3a0f85d567deff9c6d90cc0f5f7e51
@@ -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;
@@ -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
- rb_raise(oj_json_generator_error_class, "Partial character in string. 1");
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];
@@ -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 = oj_compat_parse(argc, argv, self);
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
- // TBD
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
- Yes, // empty_string
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 {
@@ -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);
@@ -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 (No == pi->options.nilnil && 0 == RSTRING_LEN(input)) {
863
- rb_raise(oj_json_parser_error_class, "An empty string is not a valid JSON string.");
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) {
@@ -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__ */
@@ -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 poviding a mark function for ruby objects on the
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) {
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '3.3.6'
4
+ VERSION = '3.3.7'
5
5
  end
@@ -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 Juby object encoding and
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
@@ -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 default differs
95
- according to the mode and in some cases the function used to load or dump. The
96
- defaults are:
97
-
98
- - :null - true
99
- - :strict - true
100
- - :compat or :json - true
101
- - JSON.parse() - false
102
- - JSON.load() - true (or what ever is set in the defaults)
103
- - :rails - TBD
104
- - :object - true
105
- - :custom - true
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.6
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-09-21 00:00:00.000000000 Z
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.13
263
+ rubygems_version: 2.6.11
264
264
  signing_key:
265
265
  specification_version: 4
266
266
  summary: A fast JSON parser and serializer.