From 7b72b13f6da24009e006a80d3693fb38cd36dde4 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 3 Aug 2022 13:56:42 -0400 Subject: [PATCH] strip quotes in storage emulator header boundary --- CHANGELOG.md | 1 + src/emulator/storage/multipart.ts | 4 +++- src/test/emulators/storage/multipart.spec.ts | 22 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04b9fc455ae..740dc8a73fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,2 @@ - Replaces underlying terminal coloring library. +- Make storage emulator multipart parsing handle quotes in boundary header #3953 diff --git a/src/emulator/storage/multipart.ts b/src/emulator/storage/multipart.ts index 54a68fc57e5..bfd5dfd0cf0 100644 --- a/src/emulator/storage/multipart.ts +++ b/src/emulator/storage/multipart.ts @@ -51,7 +51,9 @@ function splitBufferByDelimiter(buffer: Buffer, delimiter: string, maxResults = * @param body multipart request body as a Buffer */ function parseMultipartRequestBody(boundaryId: string, body: Buffer): MultipartRequestBody { - const boundaryString = `--${boundaryId}`; + // strip additional surrounding single and double quotes, cloud sdks have additional quote here + const cleanBoundaryId = boundaryId.replace(/^["'](.+(?=["']$))["']$/, "$1"); + const boundaryString = `--${cleanBoundaryId}`; const bodyParts = splitBufferByDelimiter(body, boundaryString).map((buf) => { // Remove the \r\n and the beginning of each part left from the boundary line. return Buffer.from(buf.slice(2)); diff --git a/src/test/emulators/storage/multipart.spec.ts b/src/test/emulators/storage/multipart.spec.ts index eb983e166db..cdae1726e6a 100644 --- a/src/test/emulators/storage/multipart.spec.ts +++ b/src/test/emulators/storage/multipart.spec.ts @@ -59,6 +59,28 @@ Content-Type: text/plain\r ); }); + it("parses an upload object multipart request with additional quotes in the boundary value", () => { + const contentTypeHeaderWithDoubleQuotes = `multipart/related; boundary="b1d5b2e3-1845-4338-9400-6ac07ce53c1e"`; + + let { metadataRaw, dataRaw } = parseObjectUploadMultipartRequest( + contentTypeHeaderWithDoubleQuotes, + BODY + ); + + expect(metadataRaw).to.equal('{"contentType":"text/plain"}'); + expect(dataRaw.toString()).to.equal("hello there!\n"); + + const contentTypeHeaderWithSingleQuotes = `multipart/related; boundary='b1d5b2e3-1845-4338-9400-6ac07ce53c1e'`; + + ({ metadataRaw, dataRaw } = parseObjectUploadMultipartRequest( + contentTypeHeaderWithSingleQuotes, + BODY + )); + + expect(metadataRaw).to.equal('{"contentType":"text/plain"}'); + expect(dataRaw.toString()).to.equal("hello there!\n"); + }); + it("fails to parse when body has wrong number of parts", () => { const invalidBody = Buffer.from(`--b1d5b2e3-1845-4338-9400-6ac07ce53c1e\r Content-Type: application/json\r