From ef4fd3d4cac4bc7b6b105067b730dbb14b6d0bff Mon Sep 17 00:00:00 2001 From: Vincent LE GOFF Date: Sat, 18 May 2019 20:05:27 +0200 Subject: [PATCH] Fix denoland/deno_std#409 handle multipart header in mime reader (denoland/deno_std#415) Original: https://github.com/denoland/deno_std/commit/92c26cc33183284737fd41685b26a15cab07405d --- textproto/mod.ts | 19 ++++++++++++++++++- textproto/reader_test.ts | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/textproto/mod.ts b/textproto/mod.ts index 74c7b6662d..72ecd252f2 100644 --- a/textproto/mod.ts +++ b/textproto/mod.ts @@ -83,7 +83,8 @@ export class TextProtoReader { while (true) { let [kv, err] = await this.readLineSlice(); // readContinuedLineSlice - if (kv.byteLength == 0) { + + if (kv.byteLength === 0) { return [m, err]; } @@ -140,10 +141,15 @@ export class TextProtoReader { // Go's len(typed nil) works fine, but not in JS return [new Uint8Array(0), err]; } + // Avoid the copy if the first call produced a full line. if (line == null && !more) { + if (this.skipSpace(l) === 0) { + return [new Uint8Array(0), null]; + } return [l, null]; } + line = append(line, l); if (!more) { break; @@ -151,4 +157,15 @@ export class TextProtoReader { } return [line, null]; } + + skipSpace(l: Uint8Array): number { + let n = 0; + for (let i = 0; i < l.length; i++) { + if (l[i] === charCode(" ") || l[i] === charCode("\t")) { + continue; + } + n++; + } + return n; + } } diff --git a/textproto/reader_test.ts b/textproto/reader_test.ts index b319e78099..2d054cabae 100644 --- a/textproto/reader_test.ts +++ b/textproto/reader_test.ts @@ -165,3 +165,20 @@ test({ assert(err instanceof ProtocolError); } }); + +test({ + name: "[textproto] #409 issue : multipart form boundary", + async fn(): Promise { + const input = [ + "Accept: */*\r\n", + 'Content-Disposition: form-data; name="test"\r\n', + " \r\n", + "------WebKitFormBoundaryimeZ2Le9LjohiUiG--\r\n\n" + ]; + const r = reader(input.join("")); + let [m, err] = await r.readMIMEHeader(); + assertEquals(m.get("Accept"), "*/*"); + assertEquals(m.get("Content-Disposition"), 'form-data; name="test"'); + assert(!err); + } +});