fix: sonarqube denial of service issue
This commit is contained in:
+27
-2
@@ -10,9 +10,34 @@ export function formatPrice(cents: number): string {
|
||||
return `$${(cents / 100).toFixed(2)}`;
|
||||
}
|
||||
|
||||
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
// RFC 5321 caps an address at 254 characters; reject anything longer up front so
|
||||
// validation cost stays bounded regardless of what a client posts.
|
||||
const MAX_EMAIL_LENGTH = 254;
|
||||
|
||||
// Both patterns are anchored single character classes with no overlapping
|
||||
// alternatives, so they match in linear time. Splitting on '@' and '.' in code
|
||||
// rather than in one combined pattern avoids the ambiguous (and backtracking)
|
||||
// `[^\s@]+\.[^\s@]+` domain match.
|
||||
const LOCAL_PART_RE = /^[^\s@]+$/;
|
||||
const DOMAIN_LABEL_RE = /^[^\s@.]+$/;
|
||||
|
||||
export function isValidEmail(email: string): boolean {
|
||||
return EMAIL_RE.test(email.trim());
|
||||
const trimmed = email.trim();
|
||||
if (trimmed.length === 0 || trimmed.length > MAX_EMAIL_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const at = trimmed.indexOf('@');
|
||||
if (at === -1 || at !== trimmed.lastIndexOf('@')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LOCAL_PART_RE.test(trimmed.slice(0, at))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const labels = trimmed.slice(at + 1).split('.');
|
||||
return labels.length >= 2 && labels.every((label) => DOMAIN_LABEL_RE.test(label));
|
||||
}
|
||||
|
||||
export const MARKETING_CONSENT_TEXT =
|
||||
|
||||
Reference in New Issue
Block a user