dewski/json_builder

escaping double quotes doesn't seem to work (invalid json response?)

sanderhahn opened this issue · 6 comments

From the json spec:

char
any-Unicode-character-
except-"-or--or-
control-character
"

/
\b
\f
\n
\r
\t
\u four-hex-digits

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:inparse'
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:inpretty_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:infinalize'
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:inblock 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:inrender'

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.