From 4e4a231683904dfdc1f82472ece5a160a158dbb8 Mon Sep 17 00:00:00 2001 From: Niklas von Hertzen Date: Tue, 9 Apr 2019 20:32:22 -0700 Subject: [PATCH] fix: safari data url taints (#1797) --- src/Feature.js | 41 -------------------------- src/ResourceLoader.js | 62 ++++++++++++++++++--------------------- tests/reftests/ignore.txt | 2 -- 3 files changed, 28 insertions(+), 77 deletions(-) diff --git a/src/Feature.js b/src/Feature.js index 185bd75..95a6cb8 100644 --- a/src/Feature.js +++ b/src/Feature.js @@ -27,38 +27,6 @@ const testRangeBounds = document => { return false; }; -// iOS 10.3 taints canvas with base64 images unless crossOrigin = 'anonymous' -const testBase64 = (document: Document, src: string): Promise => { - const img = new Image(); - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - - return new Promise(resolve => { - // Single pixel base64 image renders fine on iOS 10.3??? - img.src = src; - - const onload = () => { - try { - ctx.drawImage(img, 0, 0); - canvas.toDataURL(); - } catch (e) { - return resolve(false); - } - - return resolve(true); - }; - - img.onload = onload; - img.onerror = () => resolve(false); - - if (img.complete === true) { - setTimeout(() => { - onload(); - }, 500); - } - }); -}; - const testCORS = () => typeof new Image().crossOrigin !== 'undefined'; const testResponseType = () => typeof new XMLHttpRequest().responseType === 'string'; @@ -135,15 +103,6 @@ const FEATURES = { return value; }, // $FlowFixMe - get/set properties not yet supported - get SUPPORT_BASE64_DRAWING() { - 'use strict'; - return (src: string) => { - const value = testBase64(document, src); - Object.defineProperty(FEATURES, 'SUPPORT_BASE64_DRAWING', {value: () => value}); - return value; - }; - }, - // $FlowFixMe - get/set properties not yet supported get SUPPORT_FOREIGNOBJECT_DRAWING() { 'use strict'; const value = diff --git a/src/ResourceLoader.js b/src/ResourceLoader.js index 23f6191..95e87e1 100644 --- a/src/ResourceLoader.js +++ b/src/ResourceLoader.js @@ -129,42 +129,36 @@ export default class ResourceLoader { this.logger.log(`Added image ${key.substring(0, 256)}`); } - const imageLoadHandler = (supportsDataImages: boolean): Promise => - new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous - if (!supportsDataImages || useCORS) { - img.crossOrigin = 'anonymous'; - } + this.cache[key] = new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous + if (isInlineBase64Image(src) || useCORS) { + img.crossOrigin = 'anonymous'; + } - img.onerror = reject; - img.src = src; - if (img.complete === true) { - // Inline XML images may fail to parse, throwing an Error later on - setTimeout(() => { - resolve(img); - }, 500); - } - if (this.options.imageTimeout) { - const timeout = this.options.imageTimeout; - setTimeout( - () => - reject( - __DEV__ - ? `Timed out (${timeout}ms) fetching ${src.substring(0, 256)}` - : '' - ), - timeout - ); - } - }); + img.onerror = reject; + img.src = src; + if (img.complete === true) { + // Inline XML images may fail to parse, throwing an Error later on + setTimeout(() => { + resolve(img); + }, 500); + } + if (this.options.imageTimeout) { + const timeout = this.options.imageTimeout; + setTimeout( + () => + reject( + __DEV__ + ? `Timed out (${timeout}ms) fetching ${src.substring(0, 256)}` + : '' + ), + timeout + ); + } + }); - this.cache[key] = - isInlineBase64Image(src) && !isSVG(src) - ? // $FlowFixMe - FEATURES.SUPPORT_BASE64_DRAWING(src).then(imageLoadHandler) - : imageLoadHandler(true); return key; } diff --git a/tests/reftests/ignore.txt b/tests/reftests/ignore.txt index 2d83eea..e69de29 100644 --- a/tests/reftests/ignore.txt +++ b/tests/reftests/ignore.txt @@ -1,2 +0,0 @@ -[Safari]/tests/reftests/acid2.html -[Safari]/tests/reftests/background/encoded.html