Skip to content

Commit

Permalink
fix(multipart): bugs revealed by new tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Lordfirespeed committed Aug 20, 2024
1 parent 9975310 commit c5404c3
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions src/utils/split-multipart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ function isWhitespaceCharCode(charCode: number | undefined): boolean {
return charCode === linearWhitespace.at(0) || charCode === linearWhitespace.at(1)
}

function fail(): never {
throw new ClientError("Invalid multipart data", {
statusCode: 400,
code: "ERR_INVALID_MULTIPART_DATA",
})
}

/**
* Split a buffer's contents by some delimiter.
*
Expand All @@ -19,18 +26,27 @@ export function splitMultipart(toSplit: Buffer, boundary: Buffer): Buffer[]
export function splitMultipart(toSplit: Buffer, boundary: string, encoding?: BufferEncoding): Buffer[]
export function splitMultipart(toSplit: Buffer, boundary: string | Buffer, encoding?: BufferEncoding): Buffer[] {
const parts: Buffer[] = []

const boundaryWithoutNewline = Buffer.from(`--${boundary}`, encoding)
boundary = Buffer.from(`\r\n--${boundary}`, encoding)

let currentIndex = 0
let previousPartBeginIndex = 0
let seenFinalPartBoundary = false

if (toSplit.subarray(0, boundaryWithoutNewline.byteLength).equals(boundaryWithoutNewline)) {
currentIndex += boundaryWithoutNewline.byteLength
while (isWhitespaceCharCode(toSplit.at(currentIndex))) currentIndex++
if (!toSplit.subarray(currentIndex, currentIndex + CRLF.byteLength).equals(CRLF)) fail()
currentIndex += CRLF.byteLength
previousPartBeginIndex = currentIndex
parts.push(toSplit.subarray(0, 0))
}

while (true) {
currentIndex = toSplit.indexOf(boundary, currentIndex)
if (currentIndex < 0) break
if (seenFinalPartBoundary) throw new ClientError("Invalid multipart data", {
statusCode: 400,
code: "ERR_INVALID_MULTIPART_DATA",
})
if (seenFinalPartBoundary) fail()
parts.push(toSplit.subarray(previousPartBeginIndex, currentIndex))
currentIndex += boundary.byteLength

Expand All @@ -42,15 +58,15 @@ export function splitMultipart(toSplit: Buffer, boundary: string | Buffer, encod
while (isWhitespaceCharCode(toSplit.at(currentIndex))) currentIndex++

if (!toSplit.subarray(currentIndex, currentIndex + CRLF.byteLength).equals(CRLF)) {
throw new ClientError("Invalid multipart data", {
statusCode: 400,
code: "ERR_INVALID_MULTIPART_DATA",
})
if (seenFinalPartBoundary && toSplit.at(currentIndex) == null) break
fail()
}
currentIndex += CRLF.byteLength
previousPartBeginIndex = currentIndex
}

if (!seenFinalPartBoundary) fail()
parts.push(toSplit.subarray(previousPartBeginIndex))
if (parts.length < 3) fail()
return parts
}

0 comments on commit c5404c3

Please sign in to comment.