Skip to content

Commit

Permalink
fix: empty filename should not be treated as string (#28)
Browse files Browse the repository at this point in the history
Co-authored-by: Jacob Ebey <jacob.ebey@live.com>
Co-authored-by: Matt Brophy <matt@brophy.org>
  • Loading branch information
3 people committed Jul 12, 2023
1 parent 9cabb20 commit cf9ee6f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/light-snails-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/web-fetch": patch
---

If you create a FormData object on the browser with empty file input, a default empty file entry (i.e. new File([], '')) would be generated. However, this is currently presented as an empty string instead when you read it on the server. This should fix the discrepancy.
4 changes: 3 additions & 1 deletion packages/fetch/src/utils/form-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,10 @@ export const toFormData = async (source) => {
const form = new FormData()
const parts = iterateMultipart(body, boundary)
for await (const { name, data, filename, contentType } of parts) {
if (filename) {
if (typeof filename === 'string') {
form.append(name, new File([data], filename, { type: contentType }))
} else if (typeof filename !== 'undefined') {
form.append(name, new File([], '', { type: contentType }))
} else {
form.append(name, new TextDecoder().decode(data), filename)
}
Expand Down
48 changes: 48 additions & 0 deletions packages/fetch/test/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,4 +439,52 @@ describe('Request', () => {
expect(file.lastModified).to.be.a('number');
});
});

it('should decode empty file inputs into File instances (web FormData)', async () => {
const ogFormData = new WebFormData();
ogFormData.append('a', 1);
// This is what happens when you construct the form data set with an empty file input:
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set
ogFormData.append('file', new File([], '', { type: 'application/octet-stream' }));
const request = new Request(base, {
method: 'POST',
body: ogFormData,
});
const clonedRequest = request.clone();
return clonedRequest.formData().then(async clonedFormData => {
expect(clonedFormData.get('a')).to.equal("1");
const file = clonedFormData.get('file');
expect(file.name).to.equal("");
expect(file.type).to.equal("application/octet-stream");
expect(file.size).to.equal(0);
});
});

it.skip('should decode empty file inputs into File instances (node FormData)', async () => {
const ogFormData = new FormData();
ogFormData.append('a', 1);
// This is what happens when you construct the form data set with an empty file input:
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set
ogFormData.append('file', Buffer.from(''), {
// Note: This doesn't work at the moment due to https://github.com/form-data/form-data/issues/412.
// There is a v4 released which has a fix that might handle this but I
// wasn't positive if it had breaking changes that would impact us so we
// can handle an upgrade separately.
filename: '',
contentType: 'application/octet-stream',
});
const request = new Request(base, {
method: 'POST',
body: ogFormData,
});
const clonedRequest = request.clone();
return clonedRequest.formData().then(async clonedFormData => {
expect(clonedFormData.get('a')).to.equal("1");
const file = clonedFormData.get('file');
expect(file.name).to.equal("");
expect(file.type).to.equal("application/octet-stream");
expect(file.size).to.equal(0);
});

});
});

0 comments on commit cf9ee6f

Please sign in to comment.