Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs partial data just from firefox

I have a server running on nodejs, and I have the following piece of code to manage a post request -

form.on('file', function (field, file) {
   var RecordingInfo = JSON.parse(file.name);
...

when I tried to upload a file I got the following exception:

undefined:1
"}


SyntaxError: Unexpected end of input
    at Object.parse (native)
    at IncomingForm.<anonymous> (.../root.js:31:34)
...

searching around the web, I fond that this exception is caused because the data comes in bits, and the event is fired after the first bit arrives, and I don't have all the data. OK. The thing is, after a little testing I fond that from chrome I can upload large files (tried a 1.75gb file) without any problem, while firefox crashes the server with a 6kb file.

My question is - why are they different?

A sample capture can be downloaded form here. The first post is from chrome, the second from firefox.

The complete file.name string before uploading is:

// chrome
"{"subject":"flksajfd","lecturer":"אבישי וינר","path":"/גמרא","fileType":".png"}"
// firefox
"{"subject":"fdsa","lecturer":"אלקס ציקין","path":"/גמרא","fileType":".jpg"}"

(The data submitted is not the same, but I don't think it matters)

like image 321
elyashiv Avatar asked Jul 19 '26 19:07

elyashiv


1 Answers

Chrome is encoding double-quotes in the JSON-encoded "filename" as %22 while Firefox is encoding them as \".

Your file upload parsing library, Formidable, explicitly truncates the filename from the last \ character. It expects double-quotes to be encoded as %22 although RFC 2616 allows backslash-escaped quotes like Firefox has implemented. You can consider this a bug in Formidable. The result is that the following JSON string:

'{"subject":"fdsa",...,"fileType":".jpg"}'

...is encoded as follows:

'{%22subject%22:%22fdsa",...,%22fileType%22:%22.jpg%22}' // Chrome
'{\"subject\":\"fdsa\",...\"fileType\":\".jpg\"}' // Firefox

...and then decoded by Formidable:

'{"subject":"fdsa",..."fileType":".jpg"}' // Chrome
'"}' // Firefox

To fix the issue you have a few choices:

  1. Raise the issue with Formidable to correctly handle backslash-escaped quoted-value strings (or fix it yourself and submit a pull request).
  2. Send the JSON payload in a separate part of the FormData object, e.g. using a Blob.
  3. Transliterate all double-quote characters in your JSON-format filename to a 'safe' character that will not appear elsewhere in the string (I chose ^ as an example); replace the quote client-side and reinstate it server-side as follows.

Client:

    var formData = new FormData();
    formData.append('file', $scope.recording, JSON.stringify(RecordingInfo).replace(/"/g, '^');

Server

form.on('file', function (field, file) {
   var RecordingInfo = JSON.parse(file.name.replace(/\^/g, '"');
like image 101
Owen Avatar answered Jul 22 '26 12:07

Owen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!