Allow the chars from RFC 3986

This commit is contained in:
Owen 2025-02-14 12:38:28 -05:00
parent 40922fedb8
commit 7797c6c770
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD

View file

@ -11,7 +11,7 @@ export function isValidIP(ip: string): boolean {
export function isValidUrlGlobPattern(pattern: string): boolean { export function isValidUrlGlobPattern(pattern: string): boolean {
// Remove leading slash if present // Remove leading slash if present
pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern; pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
// Empty string is not valid // Empty string is not valid
if (!pattern) { if (!pattern) {
return false; return false;
@ -19,12 +19,12 @@ export function isValidUrlGlobPattern(pattern: string): boolean {
// Split path into segments // Split path into segments
const segments = pattern.split("/"); const segments = pattern.split("/");
// Check each segment // Check each segment
for (let i = 0; i < segments.length; i++) { for (let i = 0; i < segments.length; i++) {
const segment = segments[i]; const segment = segments[i];
// Empty segments are not allowed (double slashes) // Empty segments are not allowed (double slashes), except at the end
if (!segment && i !== segments.length - 1) { if (!segment && i !== segments.length - 1) {
return false; return false;
} }
@ -34,11 +34,30 @@ export function isValidUrlGlobPattern(pattern: string): boolean {
return false; return false;
} }
// Check for invalid characters // Check each character in the segment
if (!/^[a-zA-Z0-9_.*-]*$/.test(segment)) { for (let j = 0; j < segment.length; j++) {
return false; const char = segment[j];
// Check for percent-encoded sequences
if (char === "%" && j + 2 < segment.length) {
const hex1 = segment[j + 1];
const hex2 = segment[j + 2];
if (!/^[0-9A-Fa-f]$/.test(hex1) || !/^[0-9A-Fa-f]$/.test(hex2)) {
return false;
}
j += 2; // Skip the next two characters
continue;
}
// Allow:
// - unreserved (A-Z a-z 0-9 - . _ ~)
// - sub-delims (! $ & ' ( ) * + , ; =)
// - @ : for compatibility with some systems
if (!/^[A-Za-z0-9\-._~!$&'()*+,;=@:]$/.test(char)) {
return false;
}
} }
} }
return true; return true;
} }