0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

fix(ext/formdata): support multiple headers in FormData (#20801)

Fixes https://github.com/denoland/deno/issues/20793
This commit is contained in:
Marcos Casagrande 2023-10-05 19:28:44 +02:00 committed by GitHub
parent 1619932a65
commit 176bf9ba5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 16 deletions

View file

@ -155,3 +155,35 @@ Deno.test(async function bodyArrayBufferMultipleParts() {
const body = buildBody(stream);
assertEquals((await body.arrayBuffer()).byteLength, size);
});
// https://github.com/denoland/deno/issues/20793
Deno.test(
{ permissions: { net: true } },
async function bodyMultipartFormDataMultipleHeaders() {
const boundary = "----formdata-polyfill-0.970665446687947";
const payload = [
"------formdata-polyfill-0.970665446687947",
'Content-Disposition: form-data; name="x"; filename="blob"',
"Content-Length: 1",
"Content-Type: application/octet-stream",
"last-modified: Wed, 04 Oct 2023 20:28:45 GMT",
"",
"y",
"------formdata-polyfill-0.970665446687947--",
].join("\r\n");
const body = buildBody(
new TextEncoder().encode(payload),
new Headers({
"Content-Type": `multipart/form-data; boundary=${boundary}`,
}),
);
const formData = await body.formData();
const file = formData.get("x");
assert(file instanceof File);
const text = await file.text();
assertEquals(text, "y");
assertEquals(file.size, 1);
},
);

View file

@ -448,25 +448,24 @@ class MultipartParser {
const prevByte = this.body[i - 1];
const isNewLine = byte === LF && prevByte === CR;
if (state === 1 || state === 2 || state == 3) {
if (state === 1) {
headerText += StringFromCharCode(byte);
}
if (state === 0 && isNewLine) {
state = 1;
} else if (state === 1 && isNewLine) {
state = 2;
const headersDone = this.body[i + 1] === CR &&
this.body[i + 2] === LF;
if (headersDone) {
state = 3;
} else if (
state === 1
) {
if (
isNewLine && this.body[i + 1] === CR &&
this.body[i + 2] === LF
) {
// end of the headers section
state = 2;
fileStart = i + 3; // After \r\n
}
} else if (state === 2 && isNewLine) {
state = 3;
} else if (state === 3 && isNewLine) {
state = 4;
fileStart = i + 1;
} else if (state === 4) {
} else if (state === 2) {
if (this.boundaryChars[boundaryIndex] !== byte) {
boundaryIndex = 0;
} else {
@ -487,7 +486,7 @@ class MultipartParser {
const latin1Filename = MapPrototypeGet(disposition, "filename");
const latin1Name = MapPrototypeGet(disposition, "name");
state = 5;
state = 3;
// Reset
boundaryIndex = 0;
headerText = "";
@ -510,7 +509,7 @@ class MultipartParser {
formData.append(name, core.decode(content));
}
}
} else if (state === 5 && isNewLine) {
} else if (state === 3 && isNewLine) {
state = 1;
}
}