Browse Source

fix #1930: create blob in isolated world

tophf 2 years ago
parent
commit
8b9823077d

+ 2 - 1
src/injected/content/util.js

@@ -13,6 +13,7 @@ const {
 const { createElementNS } = document;
 const tdDecode = SafeTextDecoder[PROTO].decode;
 const regexpTest = RegExp[PROTO].test; // Deeply unsafe. TODO: remove.
+const { createObjectURL } = URL;
 
 /**
  * @param {string} tag
@@ -68,7 +69,7 @@ export const decodeResource = (raw, isBlob) => {
     res = isBlob ? bytes : new SafeTextDecoder()::tdDecode(bytes);
   }
   return isBlob
-    ? new SafeBlob([res], { type: mimeType })
+    ? createObjectURL(new SafeBlob([res], { type: mimeType }))
     : res;
 };
 

+ 0 - 4
src/injected/web/gm-api.js

@@ -218,10 +218,6 @@ function getResource(context, name, isBlob, isBlobAuto) {
     res = isData && isBlob === false || ensureNestedProp(resCache, bucketKey, key, false);
     if (!res) {
       res = bridge.call('GetResource', { id, isBlob, key, raw: isData && key });
-      if (res !== true && isBlob) {
-        // Creating Blob URL in page context to make it accessible for page userscripts
-        res = createObjectURL(res);
-      }
       ensureNestedProp(resCache, bucketKey, key, res);
     }
   }

+ 0 - 2
src/injected/web/safe-globals.js

@@ -53,7 +53,6 @@ export let
   // various methods
   URLToString,
   arrayIsArray,
-  createObjectURL,
   formDataEntries,
   hasOwnProperty,
   jsonParse,
@@ -144,7 +143,6 @@ export const VAULT = (() => {
     // various methods
     URLToString = res[i += 1] || src.URL[PROTO].toString,
     createNullObj = res[i += 1] || safeBind(SafeObject.create, SafeObject, null),
-    createObjectURL = res[i += 1] || src.URL.createObjectURL,
     formDataEntries = res[i += 1] || src.FormData[PROTO].entries,
     hasOwnProperty = res[i += 1] || safeBind(call, SafeObject[PROTO].hasOwnProperty),
     arrayIsArray = res[i += 1] || src.Array.isArray,

+ 1 - 1
test/injected/gm-resource.test.js

@@ -16,6 +16,6 @@ const DATA_URL = `data:${DATA.replace(',', ';base64,')}`;
 
 test('@resource decoding', async () => {
   expect(decodeResource(DATA)).toEqual(RESOURCE_TEXT);
-  expect(await blobAsText(decodeResource(DATA, true))).toEqual(RESOURCE_TEXT);
+  expect(await blobAsText(URL.blobCache[decodeResource(DATA, true)])).toEqual(RESOURCE_TEXT);
   expect(decodeResource(DATA, false)).toEqual(DATA_URL);
 });

+ 8 - 0
test/mock/polyfill.js

@@ -36,6 +36,14 @@ Object.defineProperties(global, domProps);
 delete MessagePort.prototype.onmessage; // to avoid hanging
 global.PAGE_MODE_HANDSHAKE = 123;
 global.VAULT_ID = false;
+Object.assign(URL, {
+  blobCache: {},
+  createObjectURL(blob) {
+    const blobUrl = `blob:${Math.random()}`;
+    URL.blobCache[blobUrl] = blob;
+    return blobUrl;
+  },
+});
 Object.assign(global, require('@/common/safe-globals-shared'));
 Object.assign(global, require('@/common/safe-globals'));
 Object.assign(global, require('@/injected/safe-globals'));