fix crash when decoding malformed urls (#1865)
authorAjay Bura <32841439+ajbura@users.noreply.github.com>
Sun, 4 Aug 2024 05:38:20 +0000 (11:08 +0530)
committerGitHub <noreply@github.com>
Sun, 4 Aug 2024 05:38:20 +0000 (15:38 +1000)
src/app/components/editor/input.ts
src/app/components/url-preview/UrlPreviewCard.tsx
src/app/pages/auth/AuthLayout.tsx
src/app/plugins/react-custom-html-parser.tsx
src/app/utils/dom.ts

index 29e5bd6a2abc368b7c7d5ebe8a6732b88b38c174..20c56ed319a688add62b7a658f6c214328b64ab9 100644 (file)
@@ -25,6 +25,7 @@ import {
   parseMatrixToUser,
   testMatrixTo,
 } from '../../plugins/matrix-to';
+import { tryDecodeURIComponent } from '../../utils/dom';
 
 const markNodeToType: Record<string, MarkType> = {
   b: MarkType.Bold,
@@ -73,7 +74,7 @@ const elementToInlineNode = (node: Element): MentionElement | EmoticonElement |
     return createEmoticonElement(src, alt || 'Unknown Emoji');
   }
   if (node.name === 'a') {
-    const href = decodeURIComponent(node.attribs.href);
+    const href = tryDecodeURIComponent(node.attribs.href);
     if (typeof href !== 'string') return undefined;
     if (testMatrixTo(href)) {
       const userMention = parseMatrixToUser(href);
index fc9229faf92be71cfe437bd3565bdd8d27311c05..07c25f8a152b81e9d5e5ea4eb00f579c89df77a3 100644 (file)
@@ -9,6 +9,7 @@ import {
   useIntersectionObserver,
 } from '../../hooks/useIntersectionObserver';
 import * as css from './UrlPreviewCard.css';
+import { tryDecodeURIComponent } from '../../utils/dom';
 
 const linkStyles = { color: color.Success.Main };
 
@@ -43,7 +44,7 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number }>(
               priority="300"
             >
               {typeof prev['og:site_name'] === 'string' && `${prev['og:site_name']} | `}
-              {decodeURIComponent(url)}
+              {tryDecodeURIComponent(url)}
             </Text>
             <Text truncate priority="400">
               <b>{prev['og:title']}</b>
index 2ea9414200800146c59d64f4a8d308b21de71f39..3943f42d19a123e08f9497c9835d906e1703c0e6 100644 (file)
@@ -29,6 +29,7 @@ import { AutoDiscoveryInfoProvider } from '../../hooks/useAutoDiscoveryInfo';
 import { AuthFlowsLoader } from '../../components/AuthFlowsLoader';
 import { AuthFlowsProvider } from '../../hooks/useAuthFlows';
 import { AuthServerProvider } from '../../hooks/useAuthServer';
+import { tryDecodeURIComponent } from '../../utils/dom';
 
 const currentAuthPath = (pathname: string): string => {
   if (matchPath(LOGIN_PATH, pathname)) {
@@ -72,7 +73,7 @@ export function AuthLayout() {
   const clientConfig = useClientConfig();
 
   const defaultServer = clientDefaultServer(clientConfig);
-  let server: string = urlEncodedServer ? decodeURIComponent(urlEncodedServer) : defaultServer;
+  let server: string = urlEncodedServer ? tryDecodeURIComponent(urlEncodedServer) : defaultServer;
 
   if (!clientAllowedServer(clientConfig, server)) {
     server = defaultServer;
@@ -94,7 +95,7 @@ export function AuthLayout() {
 
   // if server is mismatches with path server, update path
   useEffect(() => {
-    if (!urlEncodedServer || decodeURIComponent(urlEncodedServer) !== server) {
+    if (!urlEncodedServer || tryDecodeURIComponent(urlEncodedServer) !== server) {
       navigate(
         generatePath(currentAuthPath(location.pathname), {
           server: encodeURIComponent(server),
index 1670437452b74a8b2fda6a5ee24180072385f9d0..95e2f3342960fa0e86e021e63deb1fffde1076bc 100644 (file)
@@ -26,6 +26,7 @@ import {
   testMatrixTo,
 } from './matrix-to';
 import { onEnterOrSpace } from '../utils/keyboard';
+import { tryDecodeURIComponent } from '../utils/dom';
 
 const ReactPrism = lazy(() => import('./react-prism/ReactPrism'));
 
@@ -134,8 +135,8 @@ export const factoryRenderLinkifyWithMention = (
     attributes,
     content,
   }) => {
-    if (tagName === 'a' && testMatrixTo(decodeURIComponent(attributes.href))) {
-      const mention = mentionRender(decodeURIComponent(attributes.href));
+    if (tagName === 'a' && testMatrixTo(tryDecodeURIComponent(attributes.href))) {
+      const mention = mentionRender(tryDecodeURIComponent(attributes.href));
       if (mention) return mention;
     }
 
@@ -325,11 +326,11 @@ export const getReactCustomHtmlParser = (
           }
         }
 
-        if (name === 'a' && testMatrixTo(decodeURIComponent(props.href))) {
+        if (name === 'a' && testMatrixTo(tryDecodeURIComponent(props.href))) {
           const mention = renderMatrixMention(
             mx,
             roomId,
-            decodeURIComponent(props.href),
+            tryDecodeURIComponent(props.href),
             makeMentionCustomProps(params.handleMentionClick)
           );
           if (mention) return mention;
index 1aea6754c682fdeb1ab8c03967ed73d6bc7456cf..ab4b8e65c4654e6838bffeecb9185ba726b6a7b2 100644 (file)
@@ -196,3 +196,11 @@ export const setFavicon = (url: string): void => {
   if (!favicon) return;
   favicon.setAttribute('href', url);
 };
+
+export const tryDecodeURIComponent = (encodedURIComponent: string): string => {
+  try {
+    return decodeURIComponent(encodedURIComponent);
+  } catch {
+    return encodedURIComponent;
+  }
+};