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 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.