Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions lib/internal/mime.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
SafeMap,
SafeStringPrototypeSearch,
StringPrototypeCharAt,
StringPrototypeCharCodeAt,
StringPrototypeIndexOf,
StringPrototypeSlice,
StringPrototypeToLowerCase,
Expand All @@ -20,7 +21,23 @@ const NOT_HTTP_TOKEN_CODE_POINT = /[^!#$%&'*+\-.^_`|~A-Za-z0-9]/g;
const NOT_HTTP_QUOTED_STRING_CODE_POINT = /[^\t\u0020-~\u0080-\u00FF]/g;

const END_BEGINNING_WHITESPACE = /[^\r\n\t ]|$/;
const START_ENDING_WHITESPACE = /[\r\n\t ]*$/;

// Index at which the run of trailing HTTP whitespace begins, or str.length
// when there is none. Equivalent to the result of searching for
// /[\r\n\t ]*$/, but a backward scan avoids the quadratic backtracking that an
// unanchored search performs on a long internal whitespace run.
function startOfTrailingWhitespace(str) {
let i = str.length;
while (i > 0) {
const c = StringPrototypeCharCodeAt(str, i - 1);
if (c === 0x09 || c === 0x0A || c === 0x0D || c === 0x20) {
i--;
} else {
break;
}
}
return i;
}

function toASCIILower(str) {
// eslint-disable-next-line no-control-regex
Expand Down Expand Up @@ -68,7 +85,7 @@ function parseTypeAndSubtype(str) {
const trimmedSubtype = StringPrototypeSlice(
rawSubtype,
0,
SafeStringPrototypeSearch(rawSubtype, START_ENDING_WHITESPACE));
startOfTrailingWhitespace(rawSubtype));
const invalidSubtypeIndex = SafeStringPrototypeSearch(trimmedSubtype,
NOT_HTTP_TOKEN_CODE_POINT);
if (trimmedSubtype === '' || invalidSubtypeIndex !== -1) {
Expand Down Expand Up @@ -225,9 +242,8 @@ class MIMEParams {
const paramsMap = this.#data;
let position = 0;
const str = this.#string;
const endOfSource = SafeStringPrototypeSearch(
const endOfSource = startOfTrailingWhitespace(
StringPrototypeSlice(str, position),
START_ENDING_WHITESPACE,
) + position;
while (position < endOfSource) {
// Skip any whitespace before parameter
Expand Down Expand Up @@ -291,7 +307,7 @@ class MIMEParams {
const trimmedValue = StringPrototypeSlice(
rawValue,
0,
SafeStringPrototypeSearch(rawValue, START_ENDING_WHITESPACE),
startOfTrailingWhitespace(rawValue),
);
// Ignore parameters without values
if (trimmedValue === '') continue;
Expand Down
Loading