Lines 3904-3944javascript
3905function _validateSlugFormat(slug, fieldLabel, allowSlash) {
3906 if (typeof slug !== "string") return null;
3907 // Length cap (full slug). Browsers/CDNs typically cap URLs ~2000 chars;
3908 // most CMSes cap slugs ~200. Hard cap before any other check to avoid
3909 // wasting cycles on a deliberately massive payload.
3910 if (slug.length > SLUG_MAX_LENGTH) {
3911 return `${fieldLabel} is ${slug.length} chars (max ${SLUG_MAX_LENGTH}). BD URL slugs over this length break browsers, CDNs, and email clients.`;
3913 // Reject NFKC-non-canonical slugs. NFKC compatibility-decomposes
3914 // Unicode chars that visually look like other chars (e.g. `ffi`
3915 // U+FB03 → `ffi`, full-width digits → ASCII digits, etc.). Two
3916 // slugs that decompose to the same canonical form should be the
3917 // SAME slug; allowing both creates phishing-equivalent duplicates
3918 // that bypass the duplicate-pair guard. We reject the non-
3919 // canonical form and tell the agent to use the decomposed version.
3920 const normalized = slug.normalize("NFKC");
3921 if (normalized !== slug) {
3922 return `${fieldLabel} '${slug}' contains characters that decompose to a different form under Unicode NFKC normalization (canonical: '${normalized}'). Use the canonical form to avoid creating phishing-equivalent duplicates.`;
3924 if (/[\s--]/.test(slug)) {
CriticalTrojan Source Unicode
Source contains bidi control or invisible Unicode characters associated with Trojan Source attacks.
index.jsView on unpkg · L3924 3925 return `${fieldLabel} '${slug}' contains whitespace or invisible characters, which are not allowed in BD URLs. Use hyphens instead (e.g. 'my-page' not 'my page').`;
3927 // Control + bidi chars (\p{C} = control + format + private-use, covers
3928 // RTL override U+202E + every C0/C1 control + ZWSP-class redundantly).
3929 // Future-proof: new Unicode releases that add bidi-control or format
3930 // chars are auto-rejected without spec maintenance.
3931 if (/\p{C}/u.test(slug)) {
3932 return `${fieldLabel} '${slug}' contains control or bidi-override characters (e.g. RTL override U+202E). These enable phishing-display attacks where a slug visually renders differently than its actual content.`;
3934 // Trailing dot: some routers (IIS, Windows) normalize trailing dots
3935 // away, making `about.` a duplicate-equivalent of `about`. Reject so
3936 // both can't coexist on platforms with that quirk.
3937 if (slug.endsWith(".")) {
3938 return `${fieldLabel} '${slug}' ends with a dot. Some web servers (IIS, Windows) silently strip trailing dots, making the slug a duplicate of the same name without the dot. Remove the trailing dot.`;
3940 // URL-reserved chars + RFC 3986 reserved chars + chars that enable
3941 // phishing-link shapes (`javascript:alert(1)` via `:` + `(` + `)`).
3942 // Asymmetric reject of `'` vs `"` in earlier versions left an SQLi-shape
3943 // gap. Now both blocked.
3944 // BD URL slugs (`filename`, `subscription_filename`, `post_filename`,