Przeglądaj źródła

fix #2214: data uri is always valid

tophf 1 rok temu
rodzic
commit
188f732116
2 zmienionych plików z 18 dodań i 17 usunięć
  1. 11 12
      src/background/utils/url.js
  2. 7 5
      src/common/util.js

+ 11 - 12
src/background/utils/url.js

@@ -1,4 +1,4 @@
-import { isCdnUrlRe, isRemote, makeRaw, request } from '@/common';
+import { isCdnUrlRe, isDataUri, isRemote, makeRaw, request, tryUrl } from '@/common';
 import { VM_HOME } from '@/common/consts';
 import { VM_HOME } from '@/common/consts';
 import limitConcurrency from '@/common/limit-concurrency';
 import limitConcurrency from '@/common/limit-concurrency';
 import { addOwnCommands } from './init';
 import { addOwnCommands } from './init';
@@ -30,18 +30,17 @@ addOwnCommands({
  */
  */
 export function vetUrl(url, base = VM_HOME, throwOnFailure) {
 export function vetUrl(url, base = VM_HOME, throwOnFailure) {
   let res, err;
   let res, err;
-  try {
-    res = new URL(url, base).href;
-    if (res.startsWith(extensionRoot) || testBlacklistNet(res)) {
-      err = 'Blacklisted';
+  if (isDataUri(url)) {
+    res = url;
+  } else {
+    res = tryUrl(url, base);
+    err = !res ? 'Invalid'
+      : (res.startsWith(extensionRoot) || testBlacklistNet(res)) && 'Blacklisted';
+    if (err) {
+      err = `${err} URL ${res || url}`;
+      if (throwOnFailure) throw err;
+      res = `data:,${err}`;
     }
     }
-  } catch {
-    err = 'Invalid';
-  }
-  if (err) {
-    err = `${err} URL ${res || url}`;
-    if (throwOnFailure) throw err;
-    res = `data:,${err}`;
   }
   }
   return res;
   return res;
 }
 }

+ 7 - 5
src/common/util.js

@@ -254,6 +254,8 @@ export async function requestLocalFile(url, options = {}) {
   });
   });
 }
 }
 
 
+const isDataUriRe = /^data:/i;
+const isHttpOrHttpsRe = /^https?:\/\//i;
 const isLocalUrlRe = re`/^(
 const isLocalUrlRe = re`/^(
   file:|
   file:|
   about:|
   about:|
@@ -300,15 +302,15 @@ export const isCdnUrlRe = re`/^https:\/\/(
     zstatic\.net
     zstatic\.net
   )
   )
 )\//ix`;
 )\//ix`;
-export const isDataUri = url => /^data:/i.test(url);
-export const isValidHttpUrl = url => /^https?:\/\//i.test(url) && tryUrl(url);
+export const isDataUri = isDataUriRe.test.bind(isDataUriRe);
+export const isValidHttpUrl = url => isHttpOrHttpsRe.test(url) && tryUrl(url);
 export const isRemote = url => url && !isLocalUrlRe.test(decodeURI(url));
 export const isRemote = url => url && !isLocalUrlRe.test(decodeURI(url));
 
 
 /** @returns {string|undefined} */
 /** @returns {string|undefined} */
-export function tryUrl(str) {
+export function tryUrl(str, base) {
   try {
   try {
-    if (str && new URL(str)) {
-      return str; // throws on invalid urls
+    if (str ?? base) {
+      return new URL(str, base).href; // throws on invalid urls
     }
     }
   } catch (e) {
   } catch (e) {
     // undefined
     // undefined