Просмотр исходного кода

use a blacklist for ignoring invalid mime-types for images (see #168 and #166)

Gildas 7 лет назад
Родитель
Сommit
bd00cc354c
1 измененных файлов с 20 добавлено и 25 удалено
  1. 20 25
      lib/single-file/single-file-core.js

+ 20 - 25
lib/single-file/single-file-core.js

@@ -317,9 +317,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 	// ---------
 	// Processor
 	// ---------
-	const PREFIXES_DATA_URI_IMAGE = ["data:image/", "data:application/"];
-	const PREFIX_DATA_URI_AUDIO = "data:audio/";
-	const PREFIX_DATA_URI_VIDEO = "data:video/";
+	const PREFIXES_FORBIDDEN_DATA_URI = ["data:text/"];
 	const PREFIX_DATA_URI_IMAGE_SVG = "data:image/svg+xml";
 	const EMPTY_IMAGE = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
 	const SCRIPT_TAG_FOUND = /<script/gi;
@@ -923,26 +921,26 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 
 		async processPageResources() {
 			const processAttributeArgs = [
-				["link[href][rel*=\"icon\"]", "href", ["data:"], false, true],
-				["object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"]", "data", [PREFIX_DATA_URI_IMAGE_SVG]],
-				["img[src], input[src][type=image]", "src", PREFIXES_DATA_URI_IMAGE, true],
-				["embed[src*=\".svg\"], embed[src*=\".pdf\"]", "src", "data:"],
-				["video[poster]", "poster", PREFIXES_DATA_URI_IMAGE],
-				["*[background]", "background", PREFIXES_DATA_URI_IMAGE],
-				["image", "xlink:href", PREFIXES_DATA_URI_IMAGE]
+				["link[href][rel*=\"icon\"]", "href", false, true],
+				["object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"]", "data"],
+				["img[src], input[src][type=image]", "src", true],
+				["embed[src*=\".svg\"], embed[src*=\".pdf\"]", "src"],
+				["video[poster]", "poster"],
+				["*[background]", "background"],
+				["image", "xlink:href"]
 			];
-			let resourcePromises = processAttributeArgs.map(([selector, attributeName, prefixDataURI, processDuplicates, removeElementIfMissing]) =>
-				ProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), attributeName, prefixDataURI, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest, processDuplicates, removeElementIfMissing)
+			let resourcePromises = processAttributeArgs.map(([selector, attributeName, processDuplicates, removeElementIfMissing]) =>
+				ProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), attributeName, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest, processDuplicates, removeElementIfMissing)
 			);
 			resourcePromises = resourcePromises.concat([
 				ProcessorHelper.processXLinks(this.doc.querySelectorAll("use"), this.baseURI, this.options, this.batchRequest),
-				ProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", PREFIXES_DATA_URI_IMAGE, this.baseURI, this.options, this.batchRequest)
+				ProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", this.baseURI, this.batchRequest)
 			]);
 			if (!this.options.removeAudioSrc) {
-				resourcePromises.push(ProcessorHelper.processAttribute(this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", [PREFIX_DATA_URI_AUDIO], this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
+				resourcePromises.push(ProcessorHelper.processAttribute(this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
 			}
 			if (!this.options.removeVideoSrc) {
-				resourcePromises.push(ProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", [PREFIX_DATA_URI_VIDEO], this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
+				resourcePromises.push(ProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
 			}
 			await Promise.all(resourcePromises);
 			ProcessorHelper.processShortcutIcons(this.doc);
@@ -1113,9 +1111,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 	const REGEXP_START_TAG = /</g;
 	const REGEXP_END_TAG = />/g;
 	const REGEXP_URL_HASH = /(#.+?)$/;
-	const PREFIX_DATA_URI_NO_MIMETYPE = "data:;";
-	const PREFIX_DATA_URI_OCTET_STREAM = /^data:(application|binary)\/octet-stream/;
-	const PREFIX_DATA_URI_NULL_STREAM = /^data:null;/;
 	const PREFIX_DATA_URI_VND = "data:application/vnd.";
 	const SINGLE_FILE_VARIABLE_NAME_PREFIX = "--sf-img-";
 
@@ -1404,7 +1399,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}
 		}
 
-		static async processAttribute(resourceElements, attributeName, prefixesDataURI, baseURI, options, cssVariables, styles, batchRequest, processDuplicates, removeElementIfMissing) {
+		static async processAttribute(resourceElements, attributeName, baseURI, options, cssVariables, styles, batchRequest, processDuplicates, removeElementIfMissing) {
 			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
 				let resourceURL = resourceElement.getAttribute(attributeName);
 				resourceURL = Util.normalizeURL(resourceURL);
@@ -1421,8 +1416,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 							if (removeElementIfMissing && content == EMPTY_DATA_URI) {
 								resourceElement.remove();
 							} else {
-								const prefixFound = prefixesDataURI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
-								if (prefixFound || content.startsWith(PREFIX_DATA_URI_NO_MIMETYPE) || content.match(PREFIX_DATA_URI_OCTET_STREAM) || content.match(PREFIX_DATA_URI_NULL_STREAM)) {
+								const forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
+								if (!forbiddenPrefixFound) {
 									const isSVG = content.startsWith(PREFIX_DATA_URI_IMAGE_SVG);
 									if (processDuplicates && duplicate && options.groupDuplicateImages && !isSVG) {
 										if (ProcessorHelper.replaceImageSource(resourceElement, SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource, options)) {
@@ -1479,7 +1474,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 			}));
 		}
 
-		static async processSrcset(resourceElements, attributeName, prefixesDataURI, baseURI, options, batchRequest) {
+		static async processSrcset(resourceElements, attributeName, baseURI, batchRequest) {
 			await Promise.all(Array.from(resourceElements).map(async resourceElement => {
 				const srcset = docUtil.parseSrcset(resourceElement.getAttribute(attributeName));
 				const srcsetValues = await Promise.all(srcset.map(async srcsetValue => {
@@ -1493,9 +1488,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
 							}
 							if (Util.testValidURL(resourceURL)) {
 								const { content } = await batchRequest.addURL(resourceURL, true);
-								const prefixFound = prefixesDataURI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
-								if (prefixFound && !content.startsWith(PREFIX_DATA_URI_NO_MIMETYPE) && !content.match(PREFIX_DATA_URI_OCTET_STREAM) && !content.match(PREFIX_DATA_URI_NULL_STREAM)) {
-									resourceElement.setAttribute(attributeName, EMPTY_IMAGE);
+								const forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
+								if (forbiddenPrefixFound) {
+									return "";
 								}
 								return content + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
 							} else {