ActiveSupport::JSON.decode does not properly handl

2019-07-21 01:39发布

Is this the expected behavior? Note how the line break character gets lost.

ruby-1.9.2-p136 :001 > ActiveSupport::JSON.decode("{\"content\": \"active\n\nsupport\"}")
 => {"content"=>"active\nsupport"}

The same happens with unicode-escaped line breaks:

ruby-1.9.2-p136 :002 > ActiveSupport::JSON.decode("{\"content\": \"active\u000a\u000asupport\"}")
 => {"content"=>"active\nsupport"}

I'm using rails 3.0.3.

2条回答
我欲成王,谁敢阻挡
2楼-- · 2019-07-21 02:17

I eventually came across this ticket: https://rails.lighthouseapp.com/projects/8994/tickets/3479-activesupportjson-fails-to-decode-unicode-escaped-newline-and-literal-newlines

It seems this is a bug in ActiveSupport that will be fixed in Rails 3.0.5. For now I have patched activesupport and things are working as expected.

ruby-1.9.2-p136 :001 > ActiveSupport::JSON.decode("{\"content\": \"active\n\nsupport\"}")
 => {"content"=>"active\n\nsupport"}
查看更多
萌系小妹纸
3楼-- · 2019-07-21 02:33

To represent a newline in JSON data using double quotes, you must escape the newline:

ActiveSupport::JSON.decode("{\"content\": \"active\\n\\nsupport\"}")

Otherwise, you are inserting a newline into the JSON source and not the JSON data. Note that this would also work:

ActiveSupport::JSON.decode('{"content": "active\n\nsupport"}')

By using single quotes, you are no longer inserting a literal newline into the source of the JSON.

It is interesting to note the way ActiveSupport handles this by default (the default JSON backend is ActiveSupport::JSON::Backends::Yaml). By installing the json gem and changing the JSON backend to it (ActiveSupport::JSON.backend = 'JSONGem') and attempting to decode the same text (ActiveSupport::JSON.decode("{\"content\": \"active\\n\\nsupport\"}")) you get the following:

JSON::ParserError: 737: unexpected token at '{"content": "active

support"}'
查看更多
登录 后发表回答