oj icon indicating copy to clipboard operation
oj copied to clipboard

Oj.sc_parse doesn't parse primitives types when Oj.mimic_JSON is called

Open stanhu opened this issue 3 months ago • 3 comments

Here's my test case:

require 'oj'

class MyValidator < Oj::ScHandler
  def hash_start(); end
  def hash_end(); end
  def hash_key(key); end
  def hash_set(h, key, value); end
  def array_start(); end
  def array_end(); end
  def array_append(a, value); end
  def add_value(value); end
end

validator = MyValidator.new

Oj.mimic_JSON()

puts Oj.load('42')
puts Oj.sc_parse(validator, '42')

This fails with:

42
test.rb:19:in `sc_parse': Empty input (after ) at line 1, column 2 [parse.c:1074] in '42 (JSON::ParserError)
	from test.rb:19:in `<main>'

If I comment out mimic_JSON, then it works fine.

Is this expected?

stanhu avatar Sep 18 '25 19:09 stanhu

I was going to sayOj.mimic_JSON() should have no effect on Oj::ScHandler but since mimic_JSON modifies the global options JSON gem restriction on only Hash and Arrays at the top level probably kicked in. If you are call mimic_JSON then you are asking Oj to abide by the JSON gem restrictions.

ohler55 avatar Sep 18 '25 21:09 ohler55

@ohler55 I'm wondering why the behavior isn't consistent between Oj.load and Oj.sc_parse? Also it appears the SAJ parser works fine:

require 'oj'

class MyValidator < Oj::ScHandler
  def hash_start(); end
  def hash_end(); end
  def hash_key(key); end
  def hash_set(h, key, value); end
  def array_start(); end
  def array_end(); end
  def array_append(a, value); end
  def add_value(value); end
end

class MySaj
  def hash_start(key); end
  def hash_end(key); end
  def array_start(key); end
  def array_end(key); end
  def add_value(value, key); end
  def error(message, line, column); end
end

validator = MyValidator.new

Oj.mimic_JSON()

p = Oj::Parser.new(:saj)
p.handler = MySaj.new

puts "Oj.load"
puts Oj.load('42')
puts "Saj"
puts p.parse('42')
puts "Simple parse"
puts Oj.sc_parse(validator, '42')

stanhu avatar Sep 18 '25 22:09 stanhu

I would expect the saj_parse call to ignore all default options. It was the first callback parser and is deprecated in favor of the call to sc_parse.

For Oj::load the documentation says it handles all JSON element types so it ignores the JSON gem restrictions.

Oj has grown from a basic JSON parser more than 13 years ago to what it is today. Along the way additions and changes have been made but I've tried to keep all functions compatible during that growth. Throw in the attempt to be compatible with both the JSON gem and Rails and consistency across modes is lost. At this point Oj has been pretty stable for a while and I would be hesitant to alter the behavior of the parsers in any way that breaks existing users. Bug fixes, absolutely but API changes are tough to justify.

ohler55 avatar Sep 18 '25 23:09 ohler55