mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Don't render SVG nodes if it taints canvas
This commit is contained in:
parent
c765e2042f
commit
37a9249a4a
@ -25,6 +25,21 @@ const testRangeBounds = document => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const testSVG = document => {
|
||||
const img = new Image();
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
img.src = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>`;
|
||||
|
||||
try {
|
||||
ctx.drawImage(img, 0, 0);
|
||||
canvas.toDataURL();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const FEATURES = {
|
||||
// $FlowFixMe - get/set properties not yet supported
|
||||
get SUPPORT_RANGE_BOUNDS() {
|
||||
@ -32,6 +47,12 @@ const FEATURES = {
|
||||
const value = testRangeBounds(document);
|
||||
Object.defineProperty(FEATURES, 'SUPPORT_RANGE_BOUNDS', {value});
|
||||
return value;
|
||||
},
|
||||
get SUPPORT_SVG_DRAWING() {
|
||||
'use strict';
|
||||
const value = testSVG(document);
|
||||
Object.defineProperty(FEATURES, 'SUPPORT_SVG_DRAWING', {value});
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,8 @@ import type Logger from './Logger';
|
||||
export type ImageElement = Image | HTMLCanvasElement;
|
||||
type ImageCache = {[string]: Promise<?ImageElement>};
|
||||
|
||||
import FEATURES from './Feature';
|
||||
|
||||
export default class ImageLoader {
|
||||
origin: string;
|
||||
options: Options;
|
||||
@ -30,10 +32,20 @@ export default class ImageLoader {
|
||||
return src;
|
||||
}
|
||||
|
||||
if (this.options.allowTaint === true || this.isInlineImage(src) || this.isSameOrigin(src)) {
|
||||
return this.addImage(src, src);
|
||||
} else if (typeof this.options.proxy === 'string' && !this.isSameOrigin(src)) {
|
||||
// TODO proxy
|
||||
if (isSVG(src)) {
|
||||
if (this.options.allowTaint === true || FEATURES.SUPPORT_SVG_DRAWING) {
|
||||
return this.addImage(src, src);
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
this.options.allowTaint === true ||
|
||||
isInlineImage(src) ||
|
||||
this.isSameOrigin(src)
|
||||
) {
|
||||
return this.addImage(src, src);
|
||||
} else if (typeof this.options.proxy === 'string' && !this.isSameOrigin(src)) {
|
||||
// TODO proxy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,10 +55,6 @@ export default class ImageLoader {
|
||||
return key;
|
||||
}
|
||||
|
||||
isInlineImage(src: string): boolean {
|
||||
return /data:image\/.*;base64,/i.test(src);
|
||||
}
|
||||
|
||||
hasImageInCache(key: string): boolean {
|
||||
return typeof this.cache[key] !== 'undefined';
|
||||
}
|
||||
@ -112,3 +120,11 @@ export class ImageStore {
|
||||
return index === -1 ? null : this._images[index];
|
||||
}
|
||||
}
|
||||
|
||||
const INLINE_SVG = /^data:image\/svg\+xml/i;
|
||||
const INLINE_IMG = /^data:image\/.*;base64,/i;
|
||||
|
||||
const isInlineImage = (src: string): boolean => INLINE_IMG.test(src);
|
||||
|
||||
const isSVG = (src: string): boolean =>
|
||||
src.substr(-3).toLowerCase() === 'svg' || INLINE_SVG.test(src);
|
||||
|
@ -3,7 +3,7 @@ import parseRefTest from '../scripts/parse-reftest';
|
||||
import reftests from './reftests';
|
||||
import querystring from 'querystring';
|
||||
|
||||
const DOWNLOAD_REFTESTS = true;
|
||||
const DOWNLOAD_REFTESTS = false;
|
||||
const query = querystring.parse(location.search.replace(/^\?/, ''));
|
||||
|
||||
const downloadResult = (filename, data) => {
|
||||
@ -126,7 +126,7 @@ const assertPath = (result, expected, desc) => {
|
||||
|
||||
const delta = 10;
|
||||
|
||||
if (REFTEST) {
|
||||
if (REFTEST && query.refTest === 'true') {
|
||||
const RESULTS = parseRefTest(result);
|
||||
REFTEST.forEach(({action, line, ...args}, i) => {
|
||||
const RESULT = RESULTS[i];
|
||||
|
Loading…
Reference in New Issue
Block a user