From 6417f54299c1f6eaf91d6186cffc9772f498ae6c Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sun, 5 Nov 2023 19:13:38 -0500 Subject: [PATCH] Apply response filtering according to mime type Related issue: https://github.com/uBlockOrigin/uBlock-issues/issues/2833 --- src/js/traffic.js | 54 ++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/src/js/traffic.js b/src/js/traffic.js index 0195dd1ebfcbf..34373f30ce5e2 100644 --- a/src/js/traffic.js +++ b/src/js/traffic.js @@ -480,13 +480,6 @@ const onBeforeBehindTheSceneRequest = function(fctxt) { // - CSP injection const onHeadersReceived = function(details) { - // https://github.com/uBlockOrigin/uBlock-issues/issues/610 - // Process behind-the-scene requests in a special way. - if ( details.tabId < 0 ) { - if ( normalizeBehindTheSceneResponseHeaders(details) === false ) { - return; - } - } const fctxt = µb.filteringContext.fromWebrequestDetails(details); const isRootDoc = fctxt.itype === fctxt.MAIN_FRAME; @@ -522,13 +515,14 @@ const onHeadersReceived = function(details) { } } + const mime = mimeFromHeaders(responseHeaders); + // https://github.com/gorhill/uBlock/issues/2813 // Disable the blocking of large media elements if the document is itself // a media element: the resource was not prevented from loading so no // point to further block large media elements for the current document. if ( isRootDoc ) { - const contentType = headerValueFromName('content-type', responseHeaders); - if ( reMediaContentTypes.test(contentType) ) { + if ( reMediaContentTypes.test(mime) ) { pageStore.allowLargeMediaElementsUntil = 0; // Fall-through: this could be an SVG document, which supports // script tags. @@ -547,7 +541,7 @@ const onHeadersReceived = function(details) { }); } // html filtering - if ( isRootDoc || fctxt.itype === fctxt.SUB_FRAME ) { + if ( mime === 'text/html' || mime === 'application/xhtml+xml' ) { const selectors = htmlFilteringEngine.retrieve(fctxt); if ( selectors ) { jobs.push({ @@ -600,23 +594,19 @@ const reMediaContentTypes = /^(?:audio|image|video)\//; /******************************************************************************/ -// https://github.com/uBlockOrigin/uBlock-issues/issues/610 - -const normalizeBehindTheSceneResponseHeaders = function(details) { - if ( details.type !== 'xmlhttprequest' ) { return false; } - const headers = details.responseHeaders; - if ( Array.isArray(headers) === false ) { return false; } - const contentType = headerValueFromName('content-type', headers); - if ( contentType === '' ) { return false; } - if ( reMediaContentTypes.test(contentType) === false ) { return false; } - if ( contentType.startsWith('image') ) { - details.type = 'image'; - } else { - details.type = 'media'; - } - return true; +const mimeFromHeaders = headers => { + if ( Array.isArray(headers) === false ) { return ''; } + return mimeFromContentType(headerValueFromName('content-type', headers)); +}; + +const mimeFromContentType = contentType => { + const match = reContentTypeMime.exec(contentType); + if ( match === null ) { return ''; } + return match[1].toLowerCase(); }; +const reContentTypeMime = /^([^;]+)(?:;|$)/i; + /******************************************************************************/ function textResponseFilterer(session, directives) { @@ -683,7 +673,6 @@ htmlResponseFilterer.xmlSerializer = null; const bodyFilterer = (( ) => { const sessions = new Map(); - const reContentTypeDocument = /^([^;]+)(?:;|$)/i; const reContentTypeCharset = /charset=['"]?([^'" ]+)/i; const otherValidMimes = new Set([ 'application/javascript', @@ -712,12 +701,6 @@ const bodyFilterer = (( ) => { return ''; }; - const mimeFromContentType = contentType => { - const match = reContentTypeDocument.exec(contentType); - if ( match === null ) { return; } - return match[1].toLowerCase(); - }; - const charsetFromContentType = contentType => { const match = reContentTypeCharset.exec(contentType); if ( match === null ) { return; } @@ -932,6 +915,9 @@ const bodyFilterer = (( ) => { if ( contentType !== '' ) { mime = mimeFromContentType(contentType); if ( mime === undefined ) { return; } + if ( mime.startsWith('text/') === false ) { + if ( otherValidMimes.has(mime) === false ) { return; } + } charset = charsetFromContentType(contentType); if ( charset !== undefined ) { charset = textEncode.normalizeCharset(charset); @@ -941,10 +927,6 @@ const bodyFilterer = (( ) => { } } - if ( mime.startsWith('text/') === false ) { - if ( otherValidMimes.has(mime) === false ) { return; } - } - return true; } };