michalmuskala / jason

A blazing fast JSON parser and generator in pure Elixir.
Other
1.61k stars 169 forks source link

Decode failing when string has lots of spaces and special characters #148

Closed ricardoruwer closed 2 years ago

ricardoruwer commented 2 years ago

I'm working on a task to migrate from Poison to Jason but I found an issue when trying to decode a GraphQL query on our regressions tests, basically, someone just copied and pasted it from somewhere and the string has a lot of spaces, tabs, and other special characters, but it was working with Poison and now it is failing with Jason.

How to reproduce:

json = "{ \"query\": \"mutation updateSomethingAccount ($something_account: SomethingInput!)\r\n     { updateSomethingAccount(somethingAccount: $something_account)  \r\n            {isDefault    \r\n             id\r\n            email}}\", \t\r\n     \"variables\": { \r\n\t\t \t\"something_account\": {\r\n \t\t                      \"nonce\": \"fake-something-billing-agreement-nonce\",\r\n                                      \"isDefault\": true}}, \t\r\n\"operationName\": \"updateSomethingAccount\" }"
Poison.decode json
# => {:ok, ...}

Jason.decode json
# => {:error, %Jason.DecodeError{...}}
michalmuskala commented 2 years ago

The JSON does look invalid according to spec - in particular, raw \n and \r bytes are not allowed - they have to be escaped (producing \\n and \\r in string representation).

The full error message also indicates directly the issue with the \r byte:

iex(3)> Jason.decode! json
** (Jason.DecodeError) unexpected byte at position 81: 0xD ("\r")
    (jason 1.3.0) lib/jason.ex:92: Jason.decode!/2

This strictness in Jason is called out in README in the differences to Poison section. In this case Poison does not adhere to the standard, which might have various unexpected implications. As such I don't plan on changing the behaviour in Jason.