Skip to content
Merged
Show file tree
Hide file tree
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
148 changes: 136 additions & 12 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2826,7 +2826,13 @@ function requireRequest$3 () {
} else if (typeof val[i] === 'object') {
throw new InvalidArgumentError(`invalid ${key} header`)
} else {
arr.push(`${val[i]}`);
// Coerce primitives (and reject unsafe coercions such as functions
// with a crafted toString/Symbol.toPrimitive).
const str = `${val[i]}`;
if (!isValidHeaderValue(str)) {
throw new InvalidArgumentError(`invalid ${key} header`)
}
arr.push(str);
}
}
val = arr;
Expand All @@ -2837,7 +2843,12 @@ function requireRequest$3 () {
} else if (val === null) {
val = '';
} else {
// Coerce primitives (and reject unsafe coercions such as functions
// with a crafted toString/Symbol.toPrimitive).
val = `${val}`;
if (!isValidHeaderValue(val)) {
throw new InvalidArgumentError(`invalid ${key} header`)
}
}

if (headerName === 'host') {
Expand Down Expand Up @@ -8893,6 +8904,7 @@ function requireClientH1 () {
RequestContentLengthMismatchError,
ResponseContentLengthMismatchError,
RequestAbortedError,
InvalidArgumentError,
HeadersTimeoutError,
HeadersOverflowError,
SocketError,
Expand Down Expand Up @@ -9876,8 +9888,16 @@ function requireClientH1 () {
}
body = bodyStream.stream;
contentLength = bodyStream.length;
} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
headers.push('content-type', body.type);
} else if (util.isBlobLike(body) && request.contentType == null) {
const contentType = body.type;
if (contentType) {
const contentTypeValue = `${contentType}`;
if (!util.isValidHeaderValue(contentTypeValue)) {
util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header'));
return false
}
headers.push('content-type', contentTypeValue);
}
}

if (body && typeof body.read === 'function') {
Expand Down Expand Up @@ -13312,6 +13332,28 @@ function requireRetryHandler$1 () {
return new Date(retryAfter).getTime() - current
}

function validatePartialResponseContentLength (headers, range, statusCode, retryCount) {
const contentLength = headers['content-length'];
if (contentLength == null) {
return null
}

if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
return null
}

const length = Number(contentLength);
const expectedLength = range.end - range.start + 1;
if (!Number.isFinite(length) || length !== expectedLength) {
return new RequestRetryError('Content-Length mismatch', statusCode, {
headers,
data: { count: retryCount }
})
}

return null
}

class RetryHandler {
constructor (opts, handlers) {
const { retryOptions, ...dispatchOpts } = opts;
Expand Down Expand Up @@ -13526,6 +13568,12 @@ function requireRetryHandler$1 () {
return false
}

const contentLengthError = validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount);
if (contentLengthError != null) {
this.abort(contentLengthError);
return false
}

const { start, size, end = size - 1 } = contentRange;

assert(this.start === start, 'content-range mismatch');
Expand All @@ -13549,6 +13597,12 @@ function requireRetryHandler$1 () {
)
}

const contentLengthError = validatePartialResponseContentLength(headers, range, statusCode, this.retryCount);
if (contentLengthError != null) {
this.abort(contentLengthError);
return false
}

const { start, size, end = size - 1 } = range;
assert(
start != null && Number.isFinite(start),
Expand Down Expand Up @@ -23937,7 +23991,7 @@ function requireUtil$9 () {

if (
code < 0x20 || // exclude CTLs (0-31)
code === 0x7F || // DEL
code > 0x7E || // exclude DEL and non-ascii
code === 0x3B // ;
) {
throw new Error('Invalid cookie path')
Expand All @@ -23946,16 +24000,80 @@ function requireUtil$9 () {
}

/**
* I have no idea why these values aren't allowed to be honest,
* but Deno tests these. - Khafra
* <let-dig> ::= <letter> | <digit>
*
* <letter> ::= any one of the 52 alphabetic characters A through Z in
* upper case and a through z in lower case
*
* <digit> ::= any one of the ten digits 0 through 9r
*
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
* @param {number} code
*/
function isLetterOrDigit (code) {
return (
(code >= 0x30 && code <= 0x39) || // 0-9
(code >= 0x41 && code <= 0x5A) || // A-Z
(code >= 0x61 && code <= 0x7A) // a-z
)
}

/**
* Validates a cookie domain against the "preferred name syntax".
*
* <domain> ::= <subdomain> | " "
* <subdomain> ::= <label> | <subdomain> "." <label>
* <label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
* <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
* <let-dig-hyp> ::= <let-dig> | "-"
*
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
* @see https://www.rfc-editor.org/rfc/rfc1123#section-2.1
* @see https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
* @param {string} domain
*/
function validateCookieDomain (domain) {
if (
domain.startsWith('-') ||
domain.endsWith('.') ||
domain.endsWith('-')
) {
// <domain> ::= <subdomain> | " "
if (domain === ' ') {
return
}

if (domain.length > 255) {
throw new Error('Invalid cookie domain')
}

let labelLength = 0;

for (let i = 0; i < domain.length; ++i) {
const code = domain.charCodeAt(i);

if (code === 0x2E) {
if (labelLength === 0) {
throw new Error('Invalid cookie domain')
}

if (domain.charCodeAt(i - 1) === 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}

labelLength = 0;
continue
}

if (labelLength === 0 && !isLetterOrDigit(code)) {
throw new Error('Invalid cookie domain')
}

if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}

if (++labelLength > 63) {
throw new Error('Invalid cookie domain')
}
}

if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}
}
Expand Down Expand Up @@ -24098,7 +24216,13 @@ function requireUtil$9 () {

const [key, ...value] = part.split('=');

out.push(`${key.trim()}=${value.join('=')}`);
const trimmedKey = key.trim();
const joinedValue = value.join('=');

validateCookieName(trimmedKey);
validateCookieValue(joinedValue);

out.push(`${trimmedKey}=${joinedValue}`);
}

return out.join('; ')
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1208,9 +1208,9 @@ brace-expansion@^1.1.7:
concat-map "0.0.1"

brace-expansion@^5.0.2:
version "5.0.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.8.tgz#135ad0d8d808eb18eb5e0ec9a21f3a0b92ef18cf"
integrity "sha1-E1rQ2NgI6xjrXg7Joh86C5LvGM8= sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg=="
version "5.0.9"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.9.tgz#7c72438809b5fa5babf54199a1f1c281a6984fcf"
integrity "sha1-fHJDiAm1+lur9UGZofHCgaaYT88= sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg=="
dependencies:
balanced-match "^4.0.2"

Expand Down Expand Up @@ -2851,9 +2851,9 @@ js-tokens@^9.0.1:
integrity sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==

js-yaml@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.0.tgz#d1900572a7f7cf0b5f540c83673e60bad3436592"
integrity "sha1-0ZAFcqf3zwtfVAyDZz5gutNDZZI= sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="
version "4.3.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848"
integrity "sha1-ASFsAB1n9I4s1WDXCMevIQkKOEg= sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ=="
dependencies:
argparse "^2.0.1"

Expand Down Expand Up @@ -3049,9 +3049,9 @@ ms@^2.1.1, ms@^2.1.3:
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==

nanoid@^3.3.16:
version "3.3.16"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.16.tgz#a04d8ec4b1f10009d2d533947aefe4293737816c"
integrity "sha1-oE2OxLHxAAnS1TOUeu/kKTc3gWw= sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="
version "3.3.18"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.18.tgz#f66a2de1199ffde0fcf21c8a5f13106b1c081913"
integrity "sha1-9mot4Rmf/eD88hyKXxMQaxwIGRM= sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="

napi-postinstall@^0.3.0:
version "0.3.3"
Expand Down Expand Up @@ -4085,9 +4085,9 @@ undici@^5.25.4:
"@fastify/busboy" "^2.0.0"

undici@^6.23.0:
version "6.27.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-6.27.0.tgz#41f9e48f7c5a40d27376caaead8c9a9fc7bca9c4"
integrity "sha1-Qfnkj3xaQNJzdsqurYyan8e8qcQ= sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg=="
version "6.28.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-6.28.0.tgz#9f0e385744fef5021d6596c5bccd783f61193c1c"
integrity "sha1-nw44V0T+9QIdZZbFvM14P2EZPBw= sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA=="

universal-user-agent@^6.0.0:
version "6.0.1"
Expand Down
Loading