Shouldn't this work?: puts ActiveSupport::JSON.decode("abc".to_json) #17

Closed
Yardboy opened this Issue Jul 7, 2011 · 8 comments

Projects

None yet

6 participants

@Yardboy
Yardboy commented Jul 7, 2011

In 3.09 and previous this line of code worked:

ruby-1.9.2=p180 :001 > puts ActiveSupport::JSON.decode("abc".to_json)
 => "abc"

In 3.1.0.rc1 it does not, apparently due to the change to MultiJson:

ruby-1.9.2=p180 :001 > puts ActiveSupport::JSON.decode("abc".to_json)
MultiJson::DecodeError: 706: unexpected token at '"abc"'
  from /home/yardboy/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:146:in `parse'
  from /home/yardboy/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:146:in `parse'
  from /home/yardboy/.rvm/gems/ruby-1.9.2-p180/gems/multi_json-1.0.3/lib/multi_json/engines/json_gem.rb:13:in `decode'
  from /home/yardboy/.rvm/gems/ruby-1.9.2-p180/gems/multi_json-1.0.3/lib/multi_json.rb:65:in `decode'
  from /home/yardboy/.rvm/gems/ruby-1.9.2-p180/gems/activesupport-3.1.0.rc1/lib/active_support/json/decoding.rb:12:in `decode'
  from (irb):1
  from /home/yardboy/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.0.rc1/lib/rails/commands/console.rb:44:in `start'
  from /home/yardboy/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.0.rc1/lib/rails/commands/console.rb:8:in `start'
  from /home/yardboy/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.1.0.rc1/lib/rails/commands.rb:40:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `<main>'

Is there a reason for why it doesn't work, or is this a bug?

@sferik
Member
sferik commented Jul 7, 2011

In short, the answer to your question is "no, it should never have worked."

Technically speaking, the string "abc" is not valid JSON. JSON objects must either be hash-like or array-like. The fact that ActiveSupport was previously able to decode the string "abc" was a bug. Quoting from RFC 4627, which defines the JSON grammar:

A JSON text is a serialized object or array.

Your can find the complete JSON grammar at http://www.json.org/.

If you want to pass around strings in JSON, you could do something like this:

{"string" => "abc"}.to_json #=> "{\"string\":\"abc\"}"
@sferik sferik was assigned Jul 7, 2011
@sferik sferik closed this Jul 7, 2011
@Yardboy
Yardboy commented Jul 7, 2011

@sferik Thanks for the insight!

@iamnader

Then isn't the real issue with encode?

ActiveSupport::JSON.encode("hi")
=> ""hi""

I would think anything that successfully is encode via ActiveSupport::JSON should be successfully decoded

@cryo28
cryo28 commented Dec 1, 2011

Shouldn't ActiveSupport::JSON.encode in this case raise an exception?

@maxdemarzi

Erik,

Any chance we can be a little flexible with the spec here and follow ECMA instead of the RFC?

See top of page 202 of http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

"The top level JSONText production of the ECMAScript JSON grammar may consist of any JSONValue
rather than being restricted to being a JSONObject or a JSONArray as specified by RFC 4627"

It is causing issues with software that adheres to ECMA instead of RFC, and maybe we want to be inclusive rather than strict?

See http://groups.google.com/group/neo4j/browse_thread/thread/7dd6ec50d2565780 for background.

Thanks,
Max

@sferik
Member
sferik commented Jan 3, 2012

This isn't a question of willingness to be flexible with the spec.

MultiJSON is merely a lightweight abstraction layer on top of multiple JSON libraries. As such, it only provides functionality that is available across all supported JSON libraries.

The JSON library that, as of Ruby 1.9, is now part of the MRI standard library implements RFC 4627, not ECMA 262.

require 'json'
JSON.parse("\"abc\"") # raises JSON::ParserError

Until that works, MultiJSON won't support JSON string decoding.

@sferik
Member
sferik commented Jan 3, 2012

@flori @headius What are your thoughts on making the JSON library parse any JSONValue (including strings)?

@flori
flori commented Jan 3, 2012

You can do:

>> JSON.parse '"foo"', :quirks_mode => true
 # => "foo"

However, this will disable encoding detection/conversion as described in RFC 4627.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment