• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OtterJS / parsec / 10475138269

20 Aug 2024 04:05PM UTC coverage: 55.459% (+2.1%) from 53.371%
10475138269

push

github

Lordfirespeed
fix(multipart): bugs revealed by new tests

187 of 449 branches covered (41.65%)

Branch coverage included in aggregate %.

13 of 14 new or added lines in 1 file covered. (92.86%)

321 of 467 relevant lines covered (68.74%)

15.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.22
/src/utils/split-multipart.ts
1
import { Buffer } from 'node:buffer'
2
import { ClientError } from "@otterhttp/errors";
3

4
const doubleHyphen = Buffer.from("--")
8✔
5
const CRLF = Buffer.from("\r\n")
8✔
6
const linearWhitespace = Buffer.from(" \t")
8✔
7

8
function isWhitespaceCharCode(charCode: number | undefined): boolean {
9
  return charCode === linearWhitespace.at(0) || charCode === linearWhitespace.at(1)
36✔
10
}
11

12
function fail(): never {
13
  throw new ClientError("Invalid multipart data", {
2✔
14
    statusCode: 400,
15
    code: "ERR_INVALID_MULTIPART_DATA",
16
  })
17
}
18

19
/**
20
 * Split a buffer's contents by some delimiter.
21
 *
22
 * Returns an array of new {@link Buffer} objects that reference the same memory as the original,
23
 * but offset and cropped appropriately.
24
 */
25
export function splitMultipart(toSplit: Buffer, boundary: Buffer): Buffer[]
26
export function splitMultipart(toSplit: Buffer, boundary: string, encoding?: BufferEncoding): Buffer[]
27
export function splitMultipart(toSplit: Buffer, boundary: string | Buffer, encoding?: BufferEncoding): Buffer[] {
28
  const parts: Buffer[] = []
13✔
29

30
  const boundaryWithoutNewline = Buffer.from(`--${boundary}`, encoding)
13✔
31
  boundary = Buffer.from(`\r\n--${boundary}`, encoding)
13✔
32

33
  let currentIndex = 0
13✔
34
  let previousPartBeginIndex = 0
13✔
35
  let seenFinalPartBoundary = false
13✔
36

37
  if (toSplit.subarray(0, boundaryWithoutNewline.byteLength).equals(boundaryWithoutNewline)) {
13✔
38
    currentIndex += boundaryWithoutNewline.byteLength
1✔
39
    while (isWhitespaceCharCode(toSplit.at(currentIndex))) currentIndex++
1✔
40
    if (!toSplit.subarray(currentIndex, currentIndex + CRLF.byteLength).equals(CRLF)) fail()
1!
41
    currentIndex += CRLF.byteLength
1✔
42
    previousPartBeginIndex = currentIndex
1✔
43
    parts.push(toSplit.subarray(0, 0))
1✔
44
  }
45

46
  while (true) {
13✔
47
    currentIndex = toSplit.indexOf(boundary, currentIndex)
42✔
48
    if (currentIndex < 0) break
42✔
49
    if (seenFinalPartBoundary) fail()
30!
50
    parts.push(toSplit.subarray(previousPartBeginIndex, currentIndex))
30✔
51
    currentIndex += boundary.byteLength
30✔
52

53
    if (toSplit.subarray(currentIndex, currentIndex + doubleHyphen.byteLength).equals(doubleHyphen)) {
30✔
54
      currentIndex += doubleHyphen.byteLength
12✔
55
      seenFinalPartBoundary = true
12✔
56
    }
57

58
    while (isWhitespaceCharCode(toSplit.at(currentIndex))) currentIndex++
30✔
59

60
    if (!toSplit.subarray(currentIndex, currentIndex + CRLF.byteLength).equals(CRLF)) {
30✔
61
      if (seenFinalPartBoundary && toSplit.at(currentIndex) == null) break
1!
NEW
62
      fail()
×
63
    }
64
    currentIndex += CRLF.byteLength
29✔
65
    previousPartBeginIndex = currentIndex
29✔
66
  }
67

68
  if (!seenFinalPartBoundary) fail()
13✔
69
  parts.push(toSplit.subarray(previousPartBeginIndex))
12✔
70
  if (parts.length < 3) fail()
12✔
71
  return parts
11✔
72
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc