oj 3.13.14 → 3.13.16

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.
data/ext/oj/wab.c CHANGED
@@ -194,7 +194,6 @@ static void dump_time(VALUE obj, Out out) {
194
194
  time_t sec;
195
195
  long long nsec;
196
196
 
197
- #ifdef HAVE_RB_TIME_TIMESPEC
198
197
  if (16 <= sizeof(struct timespec)) {
199
198
  struct timespec ts = rb_time_timespec(obj);
200
199
 
@@ -204,10 +203,6 @@ static void dump_time(VALUE obj, Out out) {
204
203
  sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
205
204
  nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
206
205
  }
207
- #else
208
- sec = NUM2LL(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
209
- nsec = NUM2LL(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
210
- #endif
211
206
 
212
207
  assure_size(out, 36);
213
208
  // 2012-01-05T23:58:07.123456000Z
@@ -317,13 +312,13 @@ static VALUE calc_hash_key(ParseInfo pi, Val parent) {
317
312
  }
318
313
 
319
314
  static void hash_end(ParseInfo pi) {
320
- if (Yes == pi->options.trace) {
315
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
321
316
  oj_trace_parse_hash_end(pi, __FILE__, __LINE__);
322
317
  }
323
318
  }
324
319
 
325
320
  static void array_end(ParseInfo pi) {
326
- if (Yes == pi->options.trace) {
321
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
327
322
  oj_trace_parse_array_end(pi, __FILE__, __LINE__);
328
323
  }
329
324
  }
@@ -333,7 +328,7 @@ static VALUE noop_hash_key(ParseInfo pi, const char *key, size_t klen) {
333
328
  }
334
329
 
335
330
  static void add_value(ParseInfo pi, VALUE val) {
336
- if (Yes == pi->options.trace) {
331
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
337
332
  oj_trace_parse_call("add_value", pi, __FILE__, __LINE__, val);
338
333
  }
339
334
  pi->stack.head->val = val;
@@ -483,7 +478,7 @@ static VALUE cstr_to_rstr(ParseInfo pi, const char *str, size_t len) {
483
478
 
484
479
  static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
485
480
  pi->stack.head->val = cstr_to_rstr(pi, str, len);
486
- if (Yes == pi->options.trace) {
481
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
487
482
  oj_trace_parse_call("add_string", pi, __FILE__, __LINE__, pi->stack.head->val);
488
483
  }
489
484
  }
@@ -493,13 +488,13 @@ static void add_num(ParseInfo pi, NumInfo ni) {
493
488
  oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "not a number or other value");
494
489
  }
495
490
  pi->stack.head->val = oj_num_as_value(ni);
496
- if (Yes == pi->options.trace) {
491
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
497
492
  oj_trace_parse_call("add_number", pi, __FILE__, __LINE__, pi->stack.head->val);
498
493
  }
499
494
  }
500
495
 
501
496
  static VALUE start_hash(ParseInfo pi) {
502
- if (Yes == pi->options.trace) {
497
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
503
498
  oj_trace_parse_in("start_hash", pi, __FILE__, __LINE__);
504
499
  }
505
500
  if (Qnil != pi->options.hash_class) {
@@ -512,7 +507,7 @@ static void hash_set_cstr(ParseInfo pi, Val parent, const char *str, size_t len,
512
507
  volatile VALUE rval = cstr_to_rstr(pi, str, len);
513
508
 
514
509
  rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
515
- if (Yes == pi->options.trace) {
510
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
516
511
  oj_trace_parse_call("set_string", pi, __FILE__, __LINE__, rval);
517
512
  }
518
513
  }
@@ -525,20 +520,20 @@ static void hash_set_num(ParseInfo pi, Val parent, NumInfo ni) {
525
520
  }
526
521
  rval = oj_num_as_value(ni);
527
522
  rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
528
- if (Yes == pi->options.trace) {
523
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
529
524
  oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
530
525
  }
531
526
  }
532
527
 
533
528
  static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
534
529
  rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
535
- if (Yes == pi->options.trace) {
530
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
536
531
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
537
532
  }
538
533
  }
539
534
 
540
535
  static VALUE start_array(ParseInfo pi) {
541
- if (Yes == pi->options.trace) {
536
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
542
537
  oj_trace_parse_in("start_array", pi, __FILE__, __LINE__);
543
538
  }
544
539
  return rb_ary_new();
@@ -548,7 +543,7 @@ static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const c
548
543
  volatile VALUE rval = cstr_to_rstr(pi, str, len);
549
544
 
550
545
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
551
- if (Yes == pi->options.trace) {
546
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
552
547
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, rval);
553
548
  }
554
549
  }
@@ -561,14 +556,14 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
561
556
  }
562
557
  rval = oj_num_as_value(ni);
563
558
  rb_ary_push(stack_peek(&pi->stack)->val, rval);
564
- if (Yes == pi->options.trace) {
559
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
565
560
  oj_trace_parse_call("append_number", pi, __FILE__, __LINE__, rval);
566
561
  }
567
562
  }
568
563
 
569
564
  static void array_append_value(ParseInfo pi, VALUE value) {
570
565
  rb_ary_push(stack_peek(&pi->stack)->val, value);
571
- if (Yes == pi->options.trace) {
566
+ if (RB_UNLIKELY(Yes == pi->options.trace)) {
572
567
  oj_trace_parse_call("append_value", pi, __FILE__, __LINE__, value);
573
568
  }
574
569
  }
data/lib/oj/saj.rb CHANGED
@@ -1,11 +1,17 @@
1
1
  module Oj
2
- # A SAX style parse handler for JSON hence the acronym SAJ for Simple API for
3
- # JSON. The Oj::Saj handler class should be subclassed and then used with the
4
- # Oj::Saj key_parse() method. The Saj methods will then be called as the file
5
- # is parsed.
2
+ # A SAX style parse handler for JSON hence the acronym SAJ for Simple API
3
+ # for JSON. The Oj::Saj handler class can be subclassed and then used with
4
+ # the Oj::Saj key_parse() method or with the more resent
5
+ # Oj::Parser.new(:saj). The Saj methods will then be called as the file is
6
+ # parsed.
7
+ #
8
+ # With Oj::Parser.new(:saj) each method can also include a line and column
9
+ # argument so hash_start(key) could also be hash_start(key, line,
10
+ # column). The error() method is no used with Oj::Parser.new(:saj) so it
11
+ # will never be called.
6
12
  #
7
13
  # @example
8
- #
14
+ #
9
15
  # require 'oj'
10
16
  #
11
17
  # class MySaj < ::Oj::Saj
@@ -23,6 +29,14 @@ module Oj
23
29
  # Oj.saj_parse(cnt, f)
24
30
  # end
25
31
  #
32
+ # or
33
+ #
34
+ # p = Oj::Parser.new(:saj)
35
+ # p.handler = MySaj.new()
36
+ # File.open('any.json', 'r') do |f|
37
+ # p.parse(f.read)
38
+ # end
39
+ #
26
40
  # To make the desired methods active while parsing the desired method should
27
41
  # be made public in the subclasses. If the methods remain private they will
28
42
  # not be called during parsing.
@@ -61,6 +75,6 @@ module Oj
61
75
 
62
76
  def error(message, line, column)
63
77
  end
64
-
78
+
65
79
  end # Saj
66
80
  end # Oj
data/lib/oj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '3.13.14'
4
+ VERSION = '3.13.16'
5
5
  end
data/test/bar.rb CHANGED
@@ -6,4 +6,11 @@ $: << File.join(File.dirname(__FILE__), "../ext")
6
6
 
7
7
  require 'oj'
8
8
 
9
- Oj.load(%|{"time":"2021-08-16 12:12:15","a":"5","b":"5"|)
9
+ puts Oj.dump({
10
+ "float_test" => 0.25,
11
+ "nan_test" => Float::NAN,
12
+ "inf_test" => Float::INFINITY,
13
+ "minus_inf_test" => -Float::INFINITY,
14
+ "min_test" => Float::MIN,
15
+ "max_test" => Float::MAX,
16
+ }, mode: :object) # => {"float_test":0.25,"nan_test":3.3e14159265358979323846
@@ -269,6 +269,13 @@ EOT
269
269
  assert_equal too_deep_ary, ok
270
270
  ok = JSON.parse too_deep, :max_nesting => 0
271
271
  assert_equal too_deep_ary, ok
272
+
273
+ unless ENV['REAL_JSON_GEM']
274
+ # max_nesting should be reset to 0 if not included in options
275
+ # This behavior is not compatible with Ruby standard JSON gem
276
+ ok = JSON.parse too_deep, {}
277
+ assert_equal too_deep_ary, ok
278
+ end
272
279
  end
273
280
 
274
281
  def test_backslash
data/test/test_compat.rb CHANGED
@@ -488,6 +488,22 @@ class CompatJuice < Minitest::Test
488
488
  assert_equal([1,2], Oj.load(s, :mode => :compat))
489
489
  end
490
490
 
491
+ def test_parse_large_string
492
+ error = assert_raises() { Oj.load(%|{"a":"aaaaaaaaaa\0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}|) }
493
+ assert(error.message.include?('NULL byte in string'))
494
+
495
+ error = assert_raises() { Oj.load(%|{"a":"aaaaaaaaaaaaaaaaaaaa }|) }
496
+ assert(error.message.include?('quoted string not terminated'))
497
+
498
+ json =<<~JSON
499
+ {
500
+ "a": "\\u3074\\u30fc\\u305f\\u30fc",
501
+ "b": "aaaaaaaaaaaaaaaaaaaaaaaaaaaa"
502
+ }
503
+ JSON
504
+ assert_equal("ぴーたー", Oj.load(json)['a'])
505
+ end
506
+
491
507
  def dump_and_load(obj, trace=false)
492
508
  json = Oj.dump(obj)
493
509
  puts json if trace
data/test/test_file.rb CHANGED
@@ -212,6 +212,24 @@ class FileJuice < Minitest::Test
212
212
  dump_and_load(DateTime.new(2012, 6, 19), false)
213
213
  end
214
214
 
215
+ def test_load_unicode_path
216
+ json =<<~JSON
217
+ {
218
+ "x":true,
219
+ "y":58,
220
+ "z": [1,2,3]
221
+ }
222
+ JSON
223
+
224
+ Tempfile.create('file_test_conceição1.json') do |f|
225
+ f.write(json)
226
+ f.close
227
+
228
+ objects = Oj.load_file(f.path)
229
+ assert_equal(Oj.load(json), objects)
230
+ end
231
+ end
232
+
215
233
  def dump_and_load(obj, trace=false)
216
234
  filename = File.join(File.dirname(__FILE__), 'file_test.json')
217
235
  File.open(filename, "w") { |f|
@@ -5,7 +5,7 @@ $: << File.dirname(__FILE__)
5
5
 
6
6
  require 'helper'
7
7
 
8
- $json = %{{
8
+ $json = %|{
9
9
  "array": [
10
10
  {
11
11
  "num" : 3,
@@ -18,7 +18,7 @@ $json = %{{
18
18
  }
19
19
  ],
20
20
  "boolean" : true
21
- }}
21
+ }|
22
22
 
23
23
  class AllSaj < Oj::Saj
24
24
  attr_accessor :calls
@@ -53,6 +53,35 @@ class AllSaj < Oj::Saj
53
53
 
54
54
  end # AllSaj
55
55
 
56
+ class LocSaj
57
+ attr_accessor :calls
58
+
59
+ def initialize()
60
+ @calls = []
61
+ end
62
+
63
+ def hash_start(key, line, column)
64
+ @calls << [:hash_start, key, line, column]
65
+ end
66
+
67
+ def hash_end(key, line, column)
68
+ @calls << [:hash_end, key, line, column]
69
+ end
70
+
71
+ def array_start(key, line, column)
72
+ @calls << [:array_start, key, line, column]
73
+ end
74
+
75
+ def array_end(key, line, column)
76
+ @calls << [:array_end, key, line, column]
77
+ end
78
+
79
+ def add_value(value, key, line, column)
80
+ @calls << [:add_value, value, key, line, column]
81
+ end
82
+
83
+ end # LocSaj
84
+
56
85
  class SajTest < Minitest::Test
57
86
 
58
87
  def test_nil
@@ -242,4 +271,28 @@ class SajTest < Minitest::Test
242
271
  ], handler.calls)
243
272
  end
244
273
 
274
+ def test_loc
275
+ handler = LocSaj.new()
276
+ Oj::Parser.saj.handler = handler
277
+ Oj::Parser.saj.parse($json)
278
+ assert_equal([[:hash_start, nil, 1, 1],
279
+ [:array_start, 'array', 2, 12],
280
+ [:hash_start, nil, 3, 5],
281
+ [:add_value, 3, 'num', 4, 18],
282
+ [:add_value, 'message', 'string', 5, 25],
283
+ [:hash_start, 'hash', 6, 17],
284
+ [:hash_start, 'h2', 7, 17],
285
+ [:array_start, 'a', 8, 17],
286
+ [:add_value, 1, nil, 8, 20],
287
+ [:add_value, 2, nil, 8, 23],
288
+ [:add_value, 3, nil, 8, 26],
289
+ [:array_end, 'a', 8, 27],
290
+ [:hash_end, 'h2', 9, 9],
291
+ [:hash_end, 'hash', 10, 7],
292
+ [:hash_end, nil, 11, 5],
293
+ [:array_end, 'array', 12, 3],
294
+ [:add_value, true, 'boolean', 13, 18],
295
+ [:hash_end, nil, 14, 1]], handler.calls)
296
+ end
297
+
245
298
  end
data/test/test_various.rb CHANGED
@@ -345,6 +345,12 @@ class Juice < Minitest::Test
345
345
  out = Oj.dump hash
346
346
  assert_equal(%{{"key":"I \\u003c3 this"}}, out)
347
347
  end
348
+ def test_escapes_slashes_by_default_when_configured_to_do_so
349
+ hash = {'key' => "I <3 this </script>"}
350
+ Oj.default_options = {:escape_mode => :slash}
351
+ out = Oj.dump hash
352
+ assert_equal(%{{"key":"I <3 this <\\/script>"}}, out)
353
+ end
348
354
  def test_escapes_entities_when_asked_to
349
355
  hash = {'key' => "I <3 this"}
350
356
  out = Oj.dump(hash, :escape_mode => :xss_safe)
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.13.14
4
+ version: 3.13.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-03 00:00:00.000000000 Z
11
+ date: 2022-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -303,108 +303,4 @@ rubygems_version: 3.3.3
303
303
  signing_key:
304
304
  specification_version: 4
305
305
  summary: A fast JSON parser and serializer.
306
- test_files:
307
- - test/_test_active.rb
308
- - test/_test_active_mimic.rb
309
- - test/_test_mimic_rails.rb
310
- - test/activerecord/result_test.rb
311
- - test/activesupport4/decoding_test.rb
312
- - test/activesupport4/encoding_test.rb
313
- - test/activesupport4/test_helper.rb
314
- - test/activesupport5/abstract_unit.rb
315
- - test/activesupport5/decoding_test.rb
316
- - test/activesupport5/encoding_test.rb
317
- - test/activesupport5/encoding_test_cases.rb
318
- - test/activesupport5/test_helper.rb
319
- - test/activesupport5/time_zone_test_helpers.rb
320
- - test/activesupport6/abstract_unit.rb
321
- - test/activesupport6/decoding_test.rb
322
- - test/activesupport6/encoding_test.rb
323
- - test/activesupport6/encoding_test_cases.rb
324
- - test/activesupport6/test_common.rb
325
- - test/activesupport6/test_helper.rb
326
- - test/activesupport6/time_zone_test_helpers.rb
327
- - test/activesupport7/abstract_unit.rb
328
- - test/activesupport7/decoding_test.rb
329
- - test/activesupport7/encoding_test.rb
330
- - test/activesupport7/encoding_test_cases.rb
331
- - test/activesupport7/time_zone_test_helpers.rb
332
- - test/bar.rb
333
- - test/baz.rb
334
- - test/bug.rb
335
- - test/files.rb
336
- - test/foo.rb
337
- - test/helper.rb
338
- - test/isolated/shared.rb
339
- - test/isolated/test_mimic_after.rb
340
- - test/isolated/test_mimic_alone.rb
341
- - test/isolated/test_mimic_as_json.rb
342
- - test/isolated/test_mimic_before.rb
343
- - test/isolated/test_mimic_define.rb
344
- - test/isolated/test_mimic_rails_after.rb
345
- - test/isolated/test_mimic_rails_before.rb
346
- - test/isolated/test_mimic_redefine.rb
347
- - test/json_gem/json_addition_test.rb
348
- - test/json_gem/json_common_interface_test.rb
349
- - test/json_gem/json_encoding_test.rb
350
- - test/json_gem/json_ext_parser_test.rb
351
- - test/json_gem/json_fixtures_test.rb
352
- - test/json_gem/json_generator_test.rb
353
- - test/json_gem/json_generic_object_test.rb
354
- - test/json_gem/json_parser_test.rb
355
- - test/json_gem/json_string_matching_test.rb
356
- - test/json_gem/test_helper.rb
357
- - test/mem.rb
358
- - test/perf.rb
359
- - test/perf_compat.rb
360
- - test/perf_dump.rb
361
- - test/perf_fast.rb
362
- - test/perf_file.rb
363
- - test/perf_object.rb
364
- - test/perf_once.rb
365
- - test/perf_parser.rb
366
- - test/perf_saj.rb
367
- - test/perf_scp.rb
368
- - test/perf_simple.rb
369
- - test/perf_strict.rb
370
- - test/perf_wab.rb
371
- - test/prec.rb
372
- - test/sample/change.rb
373
- - test/sample/dir.rb
374
- - test/sample/doc.rb
375
- - test/sample/file.rb
376
- - test/sample/group.rb
377
- - test/sample/hasprops.rb
378
- - test/sample/layer.rb
379
- - test/sample/line.rb
380
- - test/sample/oval.rb
381
- - test/sample/rect.rb
382
- - test/sample/shape.rb
383
- - test/sample/text.rb
384
- - test/sample.rb
385
- - test/sample_json.rb
386
- - test/test_compat.rb
387
- - test/test_custom.rb
388
- - test/test_debian.rb
389
- - test/test_fast.rb
390
- - test/test_file.rb
391
- - test/test_gc.rb
392
- - test/test_generate.rb
393
- - test/test_hash.rb
394
- - test/test_integer_range.rb
395
- - test/test_null.rb
396
- - test/test_object.rb
397
- - test/test_parser.rb
398
- - test/test_parser_saj.rb
399
- - test/test_parser_usual.rb
400
- - test/test_rails.rb
401
- - test/test_saj.rb
402
- - test/test_scp.rb
403
- - test/test_strict.rb
404
- - test/test_various.rb
405
- - test/test_wab.rb
406
- - test/test_writer.rb
407
- - test/tests.rb
408
- - test/tests_mimic.rb
409
- - test/tests_mimic_addition.rb
410
- - test/zoo.rb
306
+ test_files: []