mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
ba07067b92
PR-URL: https://github.com/nodejs/node/pull/54442 Reviewed-By: James M Snell <jasnell@gmail.com>
648 lines
18 KiB
JavaScript
648 lines
18 KiB
JavaScript
/* eslint jsdoc/require-jsdoc: "error" */
|
|
|
|
'use strict';
|
|
|
|
const {
|
|
ArrayIsArray,
|
|
ArrayPrototypeIncludes,
|
|
ArrayPrototypeJoin,
|
|
ArrayPrototypeMap,
|
|
NumberIsFinite,
|
|
NumberIsInteger,
|
|
NumberIsNaN,
|
|
NumberMAX_SAFE_INTEGER,
|
|
NumberMIN_SAFE_INTEGER,
|
|
NumberParseInt,
|
|
ObjectPrototypeHasOwnProperty,
|
|
RegExpPrototypeExec,
|
|
String,
|
|
StringPrototypeToUpperCase,
|
|
StringPrototypeTrim,
|
|
} = primordials;
|
|
|
|
const {
|
|
codes: {
|
|
ERR_INVALID_ARG_TYPE: { HideStackFramesError: ERR_INVALID_ARG_TYPE },
|
|
ERR_INVALID_ARG_VALUE: { HideStackFramesError: ERR_INVALID_ARG_VALUE },
|
|
ERR_OUT_OF_RANGE: { HideStackFramesError: ERR_OUT_OF_RANGE },
|
|
ERR_SOCKET_BAD_PORT: { HideStackFramesError: ERR_SOCKET_BAD_PORT },
|
|
ERR_UNKNOWN_SIGNAL: { HideStackFramesError: ERR_UNKNOWN_SIGNAL },
|
|
},
|
|
hideStackFrames,
|
|
} = require('internal/errors');
|
|
const { normalizeEncoding } = require('internal/util');
|
|
const {
|
|
isAsyncFunction,
|
|
isArrayBufferView,
|
|
} = require('internal/util/types');
|
|
const { signals } = internalBinding('constants').os;
|
|
|
|
/**
|
|
* @param {*} value
|
|
* @returns {boolean}
|
|
*/
|
|
function isInt32(value) {
|
|
return value === (value | 0);
|
|
}
|
|
|
|
/**
|
|
* @param {*} value
|
|
* @returns {boolean}
|
|
*/
|
|
function isUint32(value) {
|
|
return value === (value >>> 0);
|
|
}
|
|
|
|
const octalReg = /^[0-7]+$/;
|
|
const modeDesc = 'must be a 32-bit unsigned integer or an octal string';
|
|
|
|
/**
|
|
* Parse and validate values that will be converted into mode_t (the S_*
|
|
* constants). Only valid numbers and octal strings are allowed. They could be
|
|
* converted to 32-bit unsigned integers or non-negative signed integers in the
|
|
* C++ land, but any value higher than 0o777 will result in platform-specific
|
|
* behaviors.
|
|
* @param {*} value Values to be validated
|
|
* @param {string} name Name of the argument
|
|
* @param {number} [def] If specified, will be returned for invalid values
|
|
* @returns {number}
|
|
*/
|
|
function parseFileMode(value, name, def) {
|
|
value ??= def;
|
|
if (typeof value === 'string') {
|
|
if (RegExpPrototypeExec(octalReg, value) === null) {
|
|
throw new ERR_INVALID_ARG_VALUE(name, value, modeDesc);
|
|
}
|
|
value = NumberParseInt(value, 8);
|
|
}
|
|
|
|
validateUint32(value, name);
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* @callback validateInteger
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @param {number} [min]
|
|
* @param {number} [max]
|
|
* @returns {asserts value is number}
|
|
*/
|
|
|
|
/** @type {validateInteger} */
|
|
const validateInteger = hideStackFrames(
|
|
(value, name, min = NumberMIN_SAFE_INTEGER, max = NumberMAX_SAFE_INTEGER) => {
|
|
if (typeof value !== 'number')
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
|
|
if (!NumberIsInteger(value))
|
|
throw new ERR_OUT_OF_RANGE(name, 'an integer', value);
|
|
if (value < min || value > max)
|
|
throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value);
|
|
},
|
|
);
|
|
|
|
/**
|
|
* @callback validateInt32
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @param {number} [min]
|
|
* @param {number} [max]
|
|
* @returns {asserts value is number}
|
|
*/
|
|
|
|
/** @type {validateInt32} */
|
|
const validateInt32 = hideStackFrames(
|
|
(value, name, min = -2147483648, max = 2147483647) => {
|
|
// The defaults for min and max correspond to the limits of 32-bit integers.
|
|
if (typeof value !== 'number') {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
|
|
}
|
|
if (!NumberIsInteger(value)) {
|
|
throw new ERR_OUT_OF_RANGE(name, 'an integer', value);
|
|
}
|
|
if (value < min || value > max) {
|
|
throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value);
|
|
}
|
|
},
|
|
);
|
|
|
|
/**
|
|
* @callback validateUint32
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @param {boolean} [positive=false]
|
|
* @returns {asserts value is number}
|
|
*/
|
|
|
|
/** @type {validateUint32} */
|
|
const validateUint32 = hideStackFrames((value, name, positive = false) => {
|
|
if (typeof value !== 'number') {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
|
|
}
|
|
if (!NumberIsInteger(value)) {
|
|
throw new ERR_OUT_OF_RANGE(name, 'an integer', value);
|
|
}
|
|
const min = positive ? 1 : 0;
|
|
// 2 ** 32 === 4294967296
|
|
const max = 4_294_967_295;
|
|
if (value < min || value > max) {
|
|
throw new ERR_OUT_OF_RANGE(name, `>= ${min} && <= ${max}`, value);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateString
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is string}
|
|
*/
|
|
|
|
/** @type {validateString} */
|
|
const validateString = hideStackFrames((value, name) => {
|
|
if (typeof value !== 'string')
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
|
|
});
|
|
|
|
/**
|
|
* @callback validateNumber
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @param {number} [min]
|
|
* @param {number} [max]
|
|
* @returns {asserts value is number}
|
|
*/
|
|
|
|
/** @type {validateNumber} */
|
|
const validateNumber = hideStackFrames((value, name, min = undefined, max) => {
|
|
if (typeof value !== 'number')
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
|
|
|
|
if ((min != null && value < min) || (max != null && value > max) ||
|
|
((min != null || max != null) && NumberIsNaN(value))) {
|
|
throw new ERR_OUT_OF_RANGE(
|
|
name,
|
|
`${min != null ? `>= ${min}` : ''}${min != null && max != null ? ' && ' : ''}${max != null ? `<= ${max}` : ''}`,
|
|
value);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateOneOf
|
|
* @template T
|
|
* @param {T} value
|
|
* @param {string} name
|
|
* @param {T[]} oneOf
|
|
*/
|
|
|
|
/** @type {validateOneOf} */
|
|
const validateOneOf = hideStackFrames((value, name, oneOf) => {
|
|
if (!ArrayPrototypeIncludes(oneOf, value)) {
|
|
const allowed = ArrayPrototypeJoin(
|
|
ArrayPrototypeMap(oneOf, (v) =>
|
|
(typeof v === 'string' ? `'${v}'` : String(v))),
|
|
', ');
|
|
const reason = 'must be one of: ' + allowed;
|
|
throw new ERR_INVALID_ARG_VALUE(name, value, reason);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateBoolean
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is boolean}
|
|
*/
|
|
|
|
/** @type {validateBoolean} */
|
|
const validateBoolean = hideStackFrames((value, name) => {
|
|
if (typeof value !== 'boolean')
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'boolean', value);
|
|
});
|
|
|
|
const kValidateObjectNone = 0;
|
|
const kValidateObjectAllowNullable = 1 << 0;
|
|
const kValidateObjectAllowArray = 1 << 1;
|
|
const kValidateObjectAllowFunction = 1 << 2;
|
|
const kValidateObjectAllowObjects = kValidateObjectAllowArray |
|
|
kValidateObjectAllowFunction;
|
|
const kValidateObjectAllowObjectsAndNull = kValidateObjectAllowNullable |
|
|
kValidateObjectAllowArray |
|
|
kValidateObjectAllowFunction;
|
|
|
|
/**
|
|
* @callback validateObject
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @param {number} [options]
|
|
*/
|
|
|
|
/** @type {validateObject} */
|
|
const validateObject = hideStackFrames(
|
|
(value, name, options = kValidateObjectNone) => {
|
|
if (options === kValidateObjectNone) {
|
|
if (value === null || ArrayIsArray(value)) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Object', value);
|
|
}
|
|
|
|
if (typeof value !== 'object') {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Object', value);
|
|
}
|
|
} else {
|
|
const throwOnNullable = (kValidateObjectAllowNullable & options) === 0;
|
|
|
|
if (throwOnNullable && value === null) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Object', value);
|
|
}
|
|
|
|
const throwOnArray = (kValidateObjectAllowArray & options) === 0;
|
|
|
|
if (throwOnArray && ArrayIsArray(value)) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Object', value);
|
|
}
|
|
|
|
const throwOnFunction = (kValidateObjectAllowFunction & options) === 0;
|
|
const typeofValue = typeof value;
|
|
|
|
if (typeofValue !== 'object' && (throwOnFunction || typeofValue !== 'function')) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Object', value);
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateDictionary - We are using the Web IDL Standard definition
|
|
* of "dictionary" here, which means any value
|
|
* whose Type is either Undefined, Null, or
|
|
* Object (which includes functions).
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @see https://webidl.spec.whatwg.org/#es-dictionary
|
|
* @see https://tc39.es/ecma262/#table-typeof-operator-results
|
|
*/
|
|
|
|
/** @type {validateDictionary} */
|
|
const validateDictionary = hideStackFrames(
|
|
(value, name) => {
|
|
if (value != null && typeof value !== 'object' && typeof value !== 'function') {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'a dictionary', value);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateArray
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @param {number} [minLength]
|
|
* @returns {asserts value is any[]}
|
|
*/
|
|
|
|
/** @type {validateArray} */
|
|
const validateArray = hideStackFrames((value, name, minLength = 0) => {
|
|
if (!ArrayIsArray(value)) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Array', value);
|
|
}
|
|
if (value.length < minLength) {
|
|
const reason = `must be longer than ${minLength}`;
|
|
throw new ERR_INVALID_ARG_VALUE(name, value, reason);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateStringArray
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is string[]}
|
|
*/
|
|
|
|
/** @type {validateStringArray} */
|
|
const validateStringArray = hideStackFrames((value, name) => {
|
|
validateArray(value, name);
|
|
for (let i = 0; i < value.length; ++i) {
|
|
// Don't use validateString here for performance reasons, as
|
|
// we would generate intermediate strings for the name.
|
|
if (typeof value[i] !== 'string') {
|
|
throw new ERR_INVALID_ARG_TYPE(`${name}[${i}]`, 'string', value[i]);
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateBooleanArray
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is boolean[]}
|
|
*/
|
|
|
|
/** @type {validateBooleanArray} */
|
|
const validateBooleanArray = hideStackFrames((value, name) => {
|
|
validateArray(value, name);
|
|
for (let i = 0; i < value.length; ++i) {
|
|
// Don't use validateBoolean here for performance reasons, as
|
|
// we would generate intermediate strings for the name.
|
|
if (value[i] !== true && value[i] !== false) {
|
|
throw new ERR_INVALID_ARG_TYPE(`${name}[${i}]`, 'boolean', value[i]);
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateAbortSignalArray
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is AbortSignal[]}
|
|
*/
|
|
|
|
/** @type {validateAbortSignalArray} */
|
|
function validateAbortSignalArray(value, name) {
|
|
validateArray(value, name);
|
|
for (let i = 0; i < value.length; i++) {
|
|
const signal = value[i];
|
|
const indexedName = `${name}[${i}]`;
|
|
if (signal == null) {
|
|
throw new ERR_INVALID_ARG_TYPE(indexedName, 'AbortSignal', signal);
|
|
}
|
|
validateAbortSignal(signal, indexedName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {*} signal
|
|
* @param {string} [name='signal']
|
|
* @returns {asserts signal is keyof signals}
|
|
*/
|
|
const validateSignalName = hideStackFrames((signal, name = 'signal') => {
|
|
validateString(signal, name);
|
|
|
|
if (signals[signal] === undefined) {
|
|
if (signals[StringPrototypeToUpperCase(signal)] !== undefined) {
|
|
throw new ERR_UNKNOWN_SIGNAL(signal +
|
|
' (signals must use all capital letters)');
|
|
}
|
|
|
|
throw new ERR_UNKNOWN_SIGNAL(signal);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateBuffer
|
|
* @param {*} buffer
|
|
* @param {string} [name='buffer']
|
|
* @returns {asserts buffer is ArrayBufferView}
|
|
*/
|
|
|
|
/** @type {validateBuffer} */
|
|
const validateBuffer = hideStackFrames((buffer, name = 'buffer') => {
|
|
if (!isArrayBufferView(buffer)) {
|
|
throw new ERR_INVALID_ARG_TYPE(name,
|
|
['Buffer', 'TypedArray', 'DataView'],
|
|
buffer);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @param {string} data
|
|
* @param {string} encoding
|
|
*/
|
|
const validateEncoding = hideStackFrames((data, encoding) => {
|
|
const normalizedEncoding = normalizeEncoding(encoding);
|
|
const length = data.length;
|
|
|
|
if (normalizedEncoding === 'hex' && length % 2 !== 0) {
|
|
throw new ERR_INVALID_ARG_VALUE('encoding', encoding,
|
|
`is invalid for data of length ${length}`);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Check that the port number is not NaN when coerced to a number,
|
|
* is an integer and that it falls within the legal range of port numbers.
|
|
* @param {*} port
|
|
* @param {string} [name='Port']
|
|
* @param {boolean} [allowZero=true]
|
|
* @returns {number}
|
|
*/
|
|
const validatePort = hideStackFrames((port, name = 'Port', allowZero = true) => {
|
|
if ((typeof port !== 'number' && typeof port !== 'string') ||
|
|
(typeof port === 'string' && StringPrototypeTrim(port).length === 0) ||
|
|
+port !== (+port >>> 0) ||
|
|
port > 0xFFFF ||
|
|
(port === 0 && !allowZero)) {
|
|
throw new ERR_SOCKET_BAD_PORT(name, port, allowZero);
|
|
}
|
|
return port | 0;
|
|
});
|
|
|
|
/**
|
|
* @callback validateAbortSignal
|
|
* @param {*} signal
|
|
* @param {string} name
|
|
*/
|
|
|
|
/** @type {validateAbortSignal} */
|
|
const validateAbortSignal = hideStackFrames((signal, name) => {
|
|
if (signal !== undefined &&
|
|
(signal === null ||
|
|
typeof signal !== 'object' ||
|
|
!('aborted' in signal))) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'AbortSignal', signal);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @callback validateFunction
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is Function}
|
|
*/
|
|
|
|
/** @type {validateFunction} */
|
|
const validateFunction = hideStackFrames((value, name) => {
|
|
if (typeof value !== 'function')
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
|
|
});
|
|
|
|
/**
|
|
* @callback validatePlainFunction
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is Function}
|
|
*/
|
|
|
|
/** @type {validatePlainFunction} */
|
|
const validatePlainFunction = hideStackFrames((value, name) => {
|
|
if (typeof value !== 'function' || isAsyncFunction(value))
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
|
|
});
|
|
|
|
/**
|
|
* @callback validateUndefined
|
|
* @param {*} value
|
|
* @param {string} name
|
|
* @returns {asserts value is undefined}
|
|
*/
|
|
|
|
/** @type {validateUndefined} */
|
|
const validateUndefined = hideStackFrames((value, name) => {
|
|
if (value !== undefined)
|
|
throw new ERR_INVALID_ARG_TYPE(name, 'undefined', value);
|
|
});
|
|
|
|
/**
|
|
* @template T
|
|
* @param {T} value
|
|
* @param {string} name
|
|
* @param {T[]} union
|
|
*/
|
|
function validateUnion(value, name, union) {
|
|
if (!ArrayPrototypeIncludes(union, value)) {
|
|
throw new ERR_INVALID_ARG_TYPE(name, `('${ArrayPrototypeJoin(union, '|')}')`, value);
|
|
}
|
|
}
|
|
|
|
/*
|
|
The rules for the Link header field are described here:
|
|
https://www.rfc-editor.org/rfc/rfc8288.html#section-3
|
|
|
|
This regex validates any string surrounded by angle brackets
|
|
(not necessarily a valid URI reference) followed by zero or more
|
|
link-params separated by semicolons.
|
|
*/
|
|
const linkValueRegExp = /^(?:<[^>]*>)(?:\s*;\s*[^;"\s]+(?:=(")?[^;"\s]*\1)?)*$/;
|
|
|
|
/**
|
|
* @param {any} value
|
|
* @param {string} name
|
|
*/
|
|
const validateLinkHeaderFormat = hideStackFrames((value, name) => {
|
|
if (
|
|
typeof value === 'undefined' ||
|
|
!RegExpPrototypeExec(linkValueRegExp, value)
|
|
) {
|
|
throw new ERR_INVALID_ARG_VALUE(
|
|
name,
|
|
value,
|
|
'must be an array or string of format "</styles.css>; rel=preload; as=style"',
|
|
);
|
|
}
|
|
});
|
|
|
|
const validateInternalField = hideStackFrames((object, fieldKey, className) => {
|
|
if (typeof object !== 'object' || object === null || !ObjectPrototypeHasOwnProperty(object, fieldKey)) {
|
|
throw new ERR_INVALID_ARG_TYPE('this', className, object);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* @param {any} hints
|
|
* @return {string}
|
|
*/
|
|
const validateLinkHeaderValue = hideStackFrames((hints) => {
|
|
if (typeof hints === 'string') {
|
|
validateLinkHeaderFormat.withoutStackTrace(hints, 'hints');
|
|
return hints;
|
|
} else if (ArrayIsArray(hints)) {
|
|
const hintsLength = hints.length;
|
|
let result = '';
|
|
|
|
if (hintsLength === 0) {
|
|
return result;
|
|
}
|
|
|
|
for (let i = 0; i < hintsLength; i++) {
|
|
const link = hints[i];
|
|
validateLinkHeaderFormat.withoutStackTrace(link, 'hints');
|
|
result += link;
|
|
|
|
if (i !== hintsLength - 1) {
|
|
result += ', ';
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
throw new ERR_INVALID_ARG_VALUE(
|
|
'hints',
|
|
hints,
|
|
'must be an array or string of format "</styles.css>; rel=preload; as=style"',
|
|
);
|
|
});
|
|
|
|
// 1. Returns false for undefined and NaN
|
|
// 2. Returns true for finite numbers
|
|
// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers
|
|
// 4. Throws ERR_OUT_OF_RANGE for infinite numbers
|
|
const validateFiniteNumber = hideStackFrames((number, name) => {
|
|
// Common case
|
|
if (number === undefined) {
|
|
return false;
|
|
}
|
|
|
|
if (NumberIsFinite(number)) {
|
|
return true; // Is a valid number
|
|
}
|
|
|
|
if (NumberIsNaN(number)) {
|
|
return false;
|
|
}
|
|
|
|
validateNumber(number, name);
|
|
|
|
// Infinite numbers
|
|
throw new ERR_OUT_OF_RANGE(name, 'a finite number', number);
|
|
});
|
|
|
|
// 1. Returns def for number when it's undefined or NaN
|
|
// 2. Returns number for finite numbers >= lower and <= upper
|
|
// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers
|
|
// 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower
|
|
const checkRangesOrGetDefault = hideStackFrames(
|
|
(number, name, lower, upper, def) => {
|
|
if (!validateFiniteNumber(number, name)) {
|
|
return def;
|
|
}
|
|
if (number < lower || number > upper) {
|
|
throw new ERR_OUT_OF_RANGE(name, `>= ${lower} and <= ${upper}`, number);
|
|
}
|
|
return number;
|
|
},
|
|
);
|
|
|
|
module.exports = {
|
|
isInt32,
|
|
isUint32,
|
|
parseFileMode,
|
|
validateArray,
|
|
validateStringArray,
|
|
validateBooleanArray,
|
|
validateAbortSignalArray,
|
|
validateBoolean,
|
|
validateBuffer,
|
|
validateDictionary,
|
|
validateEncoding,
|
|
validateFunction,
|
|
validateInt32,
|
|
validateInteger,
|
|
validateNumber,
|
|
validateObject,
|
|
kValidateObjectNone,
|
|
kValidateObjectAllowNullable,
|
|
kValidateObjectAllowArray,
|
|
kValidateObjectAllowFunction,
|
|
kValidateObjectAllowObjects,
|
|
kValidateObjectAllowObjectsAndNull,
|
|
validateOneOf,
|
|
validatePlainFunction,
|
|
validatePort,
|
|
validateSignalName,
|
|
validateString,
|
|
validateUint32,
|
|
validateUndefined,
|
|
validateUnion,
|
|
validateAbortSignal,
|
|
validateLinkHeaderValue,
|
|
validateInternalField,
|
|
validateFiniteNumber,
|
|
checkRangesOrGetDefault,
|
|
};
|