dewski / json_builder

Rails provides an excellent XML Builder by default to build RSS and ATOM feeds, but nothing to help you build complex and custom JSON data structures. JSON Builder is here to help.
http://garrettbjerkhoel.com/json_builder/
MIT License
244 stars 52 forks source link

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

Closed sanderhahn closed 12 years ago

sanderhahn commented 12 years ago

From the json spec:

char any-Unicode-character- except-"-or--or- control-character \" \ \/ \b \f \n \r \t \u four-hex-digits

pkoch commented 12 years ago

Can't really tell what's the problem. How can one reproduce this issue?

sanderhahn commented 12 years ago
# 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'

rickygu commented 12 years ago

I got the same error. does json builder sanitize the output by escaping all json escape characters?

sanderhahn commented 12 years ago

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).

jkloian commented 12 years ago

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

dewski commented 12 years ago

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.