Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Response: 400 JSON parse error: Unexpected end of input #719

Closed
leoliu opened this issue Feb 17, 2016 · 12 comments
Closed

Response: 400 JSON parse error: Unexpected end of input #719

leoliu opened this issue Feb 17, 2016 · 12 comments

Comments

@leoliu
Copy link

leoliu commented Feb 17, 2016

The terminal running tern --verbose prints

Response: 400 JSON parse error: Unexpected end of input

after sending the following JSON document to the tern server:

{"files":[{"type":"full","name":"/Users/ok/sources/js/tern/lib/tern.js","text":"..."}]}

where ... is the JSON string of the file tern.js.

Note also tern server replies successfully if sent JSON doc:

{"files":[{"type":"full","name":"\/Users\/ok\/sources\/js\/tern\/lib\/tern.js","text":"..."}]}

or

{"files":[{"type":"full","name":"lib/tern.js","text":"..."}]}

I wonder if there is bug somewhere? I noticed this problem after observing some behaviour difference in emacs 24.5 and 25.0.91.

Thanks,
Leo

@leoliu
Copy link
Author

leoliu commented Feb 18, 2016

In case this isn't obvious. The issue is why a absolute path encoded differently but legally (i.e. with or without \) makes a difference to the Tern server?

@marijnh
Copy link
Member

marijnh commented Feb 18, 2016

All the existing plugins are sending regular unescaped slashes in filenames, and that works. The error comes from JSON.parse, which is part of node.js, and not something Tern implements itself.

Could you show the full JSON data that causes the problem? Does JSON.parse accept it?

@leoliu
Copy link
Author

leoliu commented Feb 22, 2016

Hi @marijnh,

Thanks for your reply and sorry for my delay.

I have come up with a recipe to reproduce the problem. The problem only exhibits in emacs 25 so you will need that. It will also use the tern project.

  1. In the terminal, enter the tern project root directory and run tern --verbose which will start the tern server and print the listening port.
  2. start emacs 25 and create the following command:
(defun test ()
  (interactive)
  (let* ((url-request-method "POST")
         (url-request-extra-headers '(("Content-Type" . "application/json")))
         (url-request-data
          (json-encode `(("files" . [(:type "full"
                                            :name ,buffer-file-name
                                            :text ,(buffer-string))]))))
         (url (format "http://127.0.0.1:%d/" 53305)))
    (url-retrieve-synchronously url)))

Change 53305 to the actual port printed in step 1.
3. Open tern.js in emacs and M-x test
4. Check the terminal that is running tern server and you should see Response: 400 JSON parse error: Unexpected end of input.

The full JSON data is pasted in https://bpaste.net/show/0563125585d9 which JSON.parse seems to happily accept.

Leo

@leoliu
Copy link
Author

leoliu commented Mar 6, 2016

Hi @marijnh,

I wonder if you have time to look at this issue. I think only the json.el from 25.x is needed to reproduce the error in case you don't have emacs 25 ready. But json.el in 25 also depends on one of its new libs map.el.

Thanks,
Leo

@marijnh
Copy link
Member

marijnh commented Apr 11, 2016

That information seems to point towards a bug (or backwards incompatibility) in the JSON serializer that ships with Emacs 25. Have you tried adding a logging statement just before the JSON.parse call near the end of bin/tern to see what it is actually choking on?

@leoliu
Copy link
Author

leoliu commented Jun 12, 2016

Sorry I missed your reply on this issue.

Indeed the problem seems to be with Emacs. I made a http server to catch the request sent from emacs and it stripped some chars at the end of the JSON doc leading to unbalanced parentheses. I'll speak with emacs maintainers to know what is going on.

[update] bug logged with emacs: http://debbugs.gnu.org/23750
Thanks.

@dgutov
Copy link
Contributor

dgutov commented Jun 12, 2016

@leoliu Can you verify whether json.el itself performs the encoding right? I.e. whether the problem lies in it, or in the transport layer.

@leoliu
Copy link
Author

leoliu commented Jun 12, 2016

hi @dgutov, yes the serialised json string from json-encode is perfectly fine and can be parsed back. so it seems more likely a bug in the URL package.

@dgutov
Copy link
Contributor

dgutov commented Jun 12, 2016

OK, good.

I wonder if you can reduce the scenario to something easier to debug: does URL truncate the request body in these circumstances independent of its contents? Or are buffer contents and/or using JSON somehow important?

@leoliu
Copy link
Author

leoliu commented Jun 13, 2016

url-request-data is expected to be a unibyte-string and tern.js has a utf-8 char in it; (encode-coding-string (json-encode doc) 'utf-8) fixes the error. url-http is using length to count content-length which fails when request body has non-ascii chars.

similar issue: #605.

@leoliu leoliu closed this as completed Jun 13, 2016
@dgutov
Copy link
Contributor

dgutov commented Jun 13, 2016

url-request-data is expected to be a unibyte-string

Hmm. Since it's easy to make a mistake, maybe URL should check whether the string it's passed is multibyte.

@leoliu
Copy link
Author

leoliu commented Jun 13, 2016

Agreed. There is a fixme in url-http-create-request that alludes to signal an error instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants