Closed sanderhahn closed 12 years ago
Can't really tell what's the problem. How can one reproduce this issue?
# views/home/test.json.json_builder
valid_escapes "\"\\\/\b\f\n\r\t"
-- result in:
JSON::ParserError in Home#test Showing /work/json_builder_error/JsonBuilderError/app/views/home/test.json.json_builder where line #2 raised: 756: unexpected token at '{"valid_escapes": ""\/\f\n\r\t"}'
vendor/bundle/gems/json-1.6.6/lib/json/common.rb:148:in parse' vendor/bundle/gems/json-1.6.6/lib/json/common.rb:148:in
parse'
vendor/bundle/gems/json-1.6.6/lib/json/common.rb:13:in []' vendor/bundle/gems/json_builder-3.1.2/lib/json_builder/compiler.rb:147:in
pretty_print'
vendor/bundle/gems/json_builder-3.1.2/lib/json_builder/compiler.rb:137:in include_callback' vendor/bundle/gems/json_builder-3.1.2/lib/json_builder/compiler.rb:117:in
finalize'
vendor/bundle/gems/json_builder-3.1.2/lib/json_builder/compiler.rb:17:in generate' vendor/bundle/gems/actionpack-3.2.3/lib/action_view/template.rb:143:in
block in render'
vendor/bundle/gems/activesupport-3.2.3/lib/active_support/notifications.rb:125:in instrument' vendor/bundle/gems/actionpack-3.2.3/lib/action_view/template.rb:141:in
render'
I got the same error. does json builder sanitize the output by escaping all json escape characters?
The error occurs because the invalid json is parsed for pretty printing on development. Think that the json_escape method is incomplete. Was in a hurry for a deadline and switched to the jbuilder library instead.
# extensions.rb
def json_escape
self.gsub(/\n/, '\\n').
gsub(/\r/, '\\r').
gsub(/\t/, '\\t').
gsub(/\f/, '\\f')
end
Another design would be to make the DSL build into associative arrays and use existing libraries to encode to json (with or without pretty printing).
Adding:
gsub(/"/, '\"')
to the gsubs happening in extensions solves the problem. We put the following monkey patch in production until this is fixed:
require 'json_builder'
class String
private
json_escape = instance_method(:json_escape)
define_method :json_escape do json_escape.bind(self).call.gsub(/"/, '\"') end
end
This has since been fixed and updated with how Rails handles encoding in JSON.
@sanderhahn The gem is responsible for handling encoding internally to optimize for speed, other external libraries tend to be bloated and do more than is needed for this case.
From the json spec:
char any-Unicode-character- except-"-or--or- control-character \" \ \/ \b \f \n \r \t \u four-hex-digits