Skip to content

Commit 7759ad2

Browse files
committed
re-write multipart parsing to use findBoundaryBounds
1 parent fdfc491 commit 7759ad2

File tree

1 file changed

+12
-24
lines changed

1 file changed

+12
-24
lines changed

src/Multipart.ts

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -181,35 +181,23 @@ export class Multipart implements Part {
181181
console.warn("Invalid boundary:", new TextDecoder().decode(boundary), "\nMust be 1 to 70 characters long, not end with space, and may only contain: A-Z a-z 0-9 '()+_,-./:=? and space");
182182

183183
const parts: Uint8Array[] = [];
184-
const fullBoundarySequence = Multipart.combineArrays([Multipart.CRLF, Multipart.DOUBLE_DASH, boundary]);
185-
const endBoundarySequence = Multipart.combineArrays([Multipart.CRLF, Multipart.DOUBLE_DASH, boundary, Multipart.DOUBLE_DASH]);
186184

187185
// add artificial CRLF at the start of the data
188186
const paddedData = Multipart.combineArrays([Multipart.CRLF, data]);
187+
const closingBoundaryDelimiter = Multipart.combineArrays([boundary, Multipart.DOUBLE_DASH]);
189188

190189
let start = 0;
191-
while (true) {
192-
const boundaryIndex = Multipart.findSequenceIndex(paddedData, fullBoundarySequence, start);
193-
if (boundaryIndex === -1) break;
194-
195-
let partStart = boundaryIndex + fullBoundarySequence.length;
196-
// ignore linear whitespace after boundary
197-
while (true) {
198-
const byte = paddedData[partStart];
199-
if (byte !== Multipart.SP && byte !== 0x09) break;
200-
++partStart;
201-
}
202-
// account for CRLF after boundary
203-
partStart += 2;
204-
205-
const endBoundaryIndex = Multipart.findSequenceIndex(paddedData, endBoundarySequence, partStart);
206-
if (endBoundaryIndex === -1) break;
207-
const nextBoundaryIndex = Multipart.findSequenceIndex(paddedData, fullBoundarySequence, partStart);
208-
209-
const partEnd = nextBoundaryIndex === -1 ? (endBoundaryIndex === -1 ? paddedData.length : endBoundaryIndex) : nextBoundaryIndex;
210-
211-
if (partStart < partEnd) parts.push(paddedData.slice(partStart, partEnd));
212-
start = partEnd;
190+
while (start < paddedData.length) {
191+
const boundaryIndices = Multipart.findBoundaryBounds(paddedData, boundary, start);
192+
if (boundaryIndices === null) break;
193+
const [, boundaryEnd] = boundaryIndices;
194+
const nextBoundaryIndices =
195+
Multipart.findBoundaryBounds(paddedData, boundary, boundaryEnd + 1)
196+
?? Multipart.findBoundaryBounds(paddedData, closingBoundaryDelimiter, boundaryEnd + 1);
197+
if (nextBoundaryIndices === null) break;
198+
const [nextBoundaryStart] = nextBoundaryIndices;
199+
parts.push(paddedData.slice(boundaryEnd, nextBoundaryStart));
200+
start = nextBoundaryStart;
213201
}
214202

215203
const parsedParts = parts.map(Component.parse);

0 commit comments

Comments
 (0)