sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.72k stars 1.94k forks source link

`use:enhance` with input `type="hidden"` causes significant data loss for base64-encoded images #9478

Open isaacharrisholt opened 1 year ago

isaacharrisholt commented 1 year ago

Describe the bug

When using the use:enhance directive with a form action, there is significant data loss between the client and the server. In this case, I'm passing base64-encoded PNG image data via a hidden input.

The client correctly converts to base64 and reports the correct length for the base64 image data (~1.76MB). When the data is sent to the server, the server reports that the length of the file is much less (~767kB), and the data is truncated.

I noticed this when uploading the base64-encoded data to a storage bucket and redownloading the file - only ~half the image data was transferred.

This issue disappears when the use:enhance directive is removed, and the server receives the full image.

Reproduction

https://stackblitz.com/edit/sveltejs-kit-template-default-ezby2t?file=src/routes/+page.svelte

Relevant files are:

To see the bug in action, upload the following PNG file (assuming GitHub doesn't compress it), then click the Submit button. You should see that the file size reported by the client and server differ. This issue disappears if use:enhance is removed from the form.

Note: the use of the store is not strictly necessary, but when I discovered this bug, I was working across multiple pages and using a store to transfer the data, so I've included it in this reproduction.

DALL·E 2023-02-25 11 12 02 - a load of houses being built on the planet Pluto with a fisheye perspective, digital art

Logs

Server:
{ size: 1048576, last10: 'SGZWDcghqZ' }

System Info

(from StackBlitz)
  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
  npmPackages:
    @sveltejs/adapter-auto: ^2.0.0 => 2.0.0 
    @sveltejs/kit: ^1.5.0 => 1.13.0 
    svelte: ^3.54.0 => 3.57.0 
    vite: ^4.2.0 => 4.2.1

Severity

serious, but I can work around it

Additional Information

No response

ftognetto commented 1 year ago

Me too I’m having this problem. No problem if I upload files with input type file, with node adapter I’ve correctly setup BODY_SIZE_LIMIT env.

But this is happening to me for every kind of input (input type text too) which have a value with a big length. They simply gets cutted during the submit.

I also tried to encode input value with a different format than base64 and also tried to url encode the values but still not working

isaacharrisholt commented 1 year ago

Any update on this one?

joeinnes commented 3 months ago

Same issue here. I solved it by converting the string to a blob on the client and then converting it back on the server for anyone else in future.

For some reason, SvelteKit reports a success (204), but truncates any string FormData to exactly 1MB.

I wouldn't mind so much but it's undocumented, so would be good to throw an error or something I think?