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
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ Throws a `TypeError` if the object contains an invalid type or parameter names.

This package exposes the validation functions used by `format`:

- `isTypeValid` Validates the MIME type against RFC 9110.
- `isTokenValid` Validates a token against RFC 9110 (used for the parameter name).
- `isTypeValid(str, start?, end?)` Validates the MIME type against RFC 9110.
- `isTokenValid(str, start?, end?)` Validates a token against RFC 9110 (used for the parameter name).

Passing `start` and `end` allows for validating a subset of a string, instead of using `str#slice`.

## License

Expand Down
24 changes: 15 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,18 @@ export interface ContentType {
/**
* Validate a type string against RFC 9110.
*/
export function isTypeValid(type: string): boolean {
const len = type.length;
export function isTypeValid(
type: string,
start = 0,
end = type.length,
): boolean {
let hasSlash = false;

for (let index = 0; index < len; index++) {
for (let index = start; index < end; index++) {
const code = type.charCodeAt(index);

if (code === 47 /* / */) {
if (hasSlash || index === 0 || index === len - 1) return false;
if (hasSlash || index === start || index >= end - 1) return false;
hasSlash = true;
} else if (!isTokenCode(code)) {
return false;
Expand All @@ -89,12 +92,15 @@ export function isTypeValid(type: string): boolean {
/**
* Validate a token against RFC 9110.
*/
export function isTokenValid(name: string): boolean {
const len = name.length;
if (len === 0) return false;
export function isTokenValid(
token: string,
start = 0,
end = token.length,
): boolean {
if (start >= end) return false;

for (let index = 0; index < len; index++) {
if (!isTokenCode(name.charCodeAt(index))) return false;
for (let index = start; index < end; index++) {
if (!isTokenCode(token.charCodeAt(index))) return false;
}

return true;
Expand Down
46 changes: 46 additions & 0 deletions src/validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ describe("isTypeValid(type)", function () {
])("should reject invalid type: %s", function (type) {
assert.strictEqual(isTypeValid(type), false);
});

it("should default the end index to the string length", function () {
assert.strictEqual(isTypeValid(";text/html", 1), true);
});

it.each([
["text/html;", 0, 9, true],
[";text/html;", 1, 10, true],
[";a/b;", 1, 4, true],
[";text/html;", 0, 10, false],
[";text/html;", 1, 11, false],
[";text/html;", 5, 10, false],
[";text/html;", 1, 6, false],
[";text/html;", 1, 5, false],
[";text/html/extra;", 1, 16, false],
[";text/ plain;", 1, 12, false],
[";text/html;", 1, 1, false],
[";text/html;", 10, 1, false],
])(
"should validate type %j from %i to %i as %s",
function (type, start, end, expected) {
assert.strictEqual(isTypeValid(type, start, end), expected);
},
);
});

describe("isTokenValid(name)", function () {
Expand Down Expand Up @@ -62,4 +86,26 @@ describe("isTokenValid(name)", function () {
])("should reject invalid parameter name: %s", function (name) {
assert.strictEqual(isTokenValid(name), false);
});

it("should default the end index to the string length", function () {
assert.strictEqual(isTokenValid(";charset", 1), true);
});

it.each([
["charset=", 0, 7, true],
[";charset=", 1, 8, true],
[";a=", 1, 2, true],
[";charset=", 0, 8, false],
[";charset=", 1, 9, false],
[";char set=", 1, 9, false],
[";char/set=", 1, 9, false],
[";chärset=", 1, 8, false],
[";charset=", 1, 1, false],
[";charset=", 8, 1, false],
])(
"should validate parameter name %j from %i to %i as %s",
function (name, start, end, expected) {
assert.strictEqual(isTokenValid(name, start, end), expected);
},
);
});
Loading