Safe Link: Keep original link if decodeURI throws error (#4482)

This commit is contained in:
Alexander Zinchuk 2024-04-19 13:38:40 +04:00
parent 0631a9111d
commit bb2694dd8c
2 changed files with 13 additions and 15 deletions

View File

@ -54,7 +54,7 @@ const SafeLink: FC<OwnProps> = ({
return ( return (
<a <a
href={ensureProtocol(url)} href={ensureProtocol(url)}
title={getDomain(url)} title={getUnicodeUrl(url)}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className={classNames} className={classNames}
@ -67,7 +67,7 @@ const SafeLink: FC<OwnProps> = ({
); );
}; };
function getDomain(url?: string) { function getUnicodeUrl(url?: string) {
if (!url) { if (!url) {
return undefined; return undefined;
} }
@ -78,20 +78,18 @@ function getDomain(url?: string) {
} }
try { try {
let decodedHref = decodeURI(href.replace(/%%/g, '%25')); const parsedUrl = new URL(href);
const unicodeDomain = convertPunycode(parsedUrl.hostname);
const match = decodedHref.match(/^https?:\/\/([^/:?#]+)(?:[/:?#]|$)/i); try {
if (!match) { return decodeURI(parsedUrl.toString()).replace(parsedUrl.hostname, unicodeDomain);
return undefined; } catch (err) { // URL contains invalid sequences, keep it as it is
return parsedUrl.toString().replace(parsedUrl.hostname, unicodeDomain);
} }
const domain = match[1];
decodedHref = decodedHref.replace(domain, convertPunycode(domain));
return decodedHref;
} catch (error) { } catch (error) {
if (DEBUG) { if (DEBUG) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error('SafeLink.getDecodedUrl error ', url, error); console.warn('SafeLink.getDecodedUrl error ', url, error);
} }
} }

View File

@ -892,10 +892,6 @@
} }
} }
.long-word-break-all {
word-break: break-all;
}
.text-entity-link { .text-entity-link {
color: var(--color-links) !important; color: var(--color-links) !important;
text-decoration: none !important; text-decoration: none !important;
@ -910,6 +906,10 @@
} }
} }
.long-word-break-all {
word-break: break-all;
}
.text-entity-code { .text-entity-code {
color: var(--color-code); color: var(--color-code);
background: var(--color-code-bg); background: var(--color-code-bg);