Fix potential exceptions in new response body filtering code

Related feedback:
https://github.com/uBlockOrigin/uBlock-issues/discussions/2929

Related commit:
7c3e060c01
This commit is contained in:
Raymond Hill 2023-11-04 09:43:38 -04:00
parent 4774a39b17
commit 4de6bd6f07
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
2 changed files with 50 additions and 39 deletions

View File

@ -37,30 +37,30 @@ import {
// values -- the assumption being that integer operations are faster than
// string operations.
const NO_TYPE = 0;
const BEACON = 1 << 0;
const CSP_REPORT = 1 << 1;
const FONT = 1 << 2;
const IMAGE = 1 << 4;
const IMAGESET = 1 << 4;
const MAIN_FRAME = 1 << 5;
const MEDIA = 1 << 6;
const OBJECT = 1 << 7;
const OBJECT_SUBREQUEST = 1 << 7;
const PING = 1 << 8;
const SCRIPT = 1 << 9;
const STYLESHEET = 1 << 10;
const SUB_FRAME = 1 << 11;
const WEBSOCKET = 1 << 12;
const XMLHTTPREQUEST = 1 << 13;
const INLINE_FONT = 1 << 14;
const INLINE_SCRIPT = 1 << 15;
const OTHER = 1 << 16;
const FRAME_ANY = MAIN_FRAME | SUB_FRAME;
const FONT_ANY = FONT | INLINE_FONT;
const INLINE_ANY = INLINE_FONT | INLINE_SCRIPT;
const PING_ANY = BEACON | CSP_REPORT | PING;
const SCRIPT_ANY = SCRIPT | INLINE_SCRIPT;
export const NO_TYPE = 0;
export const BEACON = 1 << 0;
export const CSP_REPORT = 1 << 1;
export const FONT = 1 << 2;
export const IMAGE = 1 << 4;
export const IMAGESET = 1 << 4;
export const MAIN_FRAME = 1 << 5;
export const MEDIA = 1 << 6;
export const OBJECT = 1 << 7;
export const OBJECT_SUBREQUEST = 1 << 7;
export const PING = 1 << 8;
export const SCRIPT = 1 << 9;
export const STYLESHEET = 1 << 10;
export const SUB_FRAME = 1 << 11;
export const WEBSOCKET = 1 << 12;
export const XMLHTTPREQUEST = 1 << 13;
export const INLINE_FONT = 1 << 14;
export const INLINE_SCRIPT = 1 << 15;
export const OTHER = 1 << 16;
export const FRAME_ANY = MAIN_FRAME | SUB_FRAME;
export const FONT_ANY = FONT | INLINE_FONT;
export const INLINE_ANY = INLINE_FONT | INLINE_SCRIPT;
export const PING_ANY = BEACON | CSP_REPORT | PING;
export const SCRIPT_ANY = SCRIPT | INLINE_SCRIPT;
const typeStrToIntMap = {
'no_type': NO_TYPE,
@ -84,15 +84,15 @@ const typeStrToIntMap = {
'other': OTHER,
};
const METHOD_NONE = 0;
const METHOD_CONNECT = 1 << 1;
const METHOD_DELETE = 1 << 2;
const METHOD_GET = 1 << 3;
const METHOD_HEAD = 1 << 4;
const METHOD_OPTIONS = 1 << 5;
const METHOD_PATCH = 1 << 6;
const METHOD_POST = 1 << 7;
const METHOD_PUT = 1 << 8;
export const METHOD_NONE = 0;
export const METHOD_CONNECT = 1 << 1;
export const METHOD_DELETE = 1 << 2;
export const METHOD_GET = 1 << 3;
export const METHOD_HEAD = 1 << 4;
export const METHOD_OPTIONS = 1 << 5;
export const METHOD_PATCH = 1 << 6;
export const METHOD_POST = 1 << 7;
export const METHOD_PUT = 1 << 8;
const methodStrToBitMap = {
'': METHOD_NONE,
@ -128,7 +128,7 @@ const methodBitToStrMap = new Map([
/******************************************************************************/
const FilteringContext = class {
export const FilteringContext = class {
constructor(other) {
if ( other instanceof FilteringContext ) {
return this.fromFilteringContext(other);
@ -459,5 +459,3 @@ FilteringContext.prototype.METHOD_POST = FilteringContext.METHOD_POST = METHOD_P
FilteringContext.prototype.METHOD_PUT = FilteringContext.METHOD_PUT = METHOD_PUT;
/******************************************************************************/
export { FilteringContext };

View File

@ -33,6 +33,7 @@ import staticNetFilteringEngine from './static-net-filtering.js';
import textEncode from './text-encode.js';
import µb from './background.js';
import * as sfp from './static-filtering-parser.js';
import * as fc from './filtering-context.js';
import {
sessionFirewall,
@ -699,6 +700,8 @@ const bodyFilterer = (( ) => {
'application/xml',
'application/xhtml+xml',
]);
const NOT_TEXT_TYPES = fc.FONT | fc.IMAGE | fc.MEDIA | fc.WEBSOCKET;
let textDecoder, textEncoder;
const mimeFromContentType = contentType => {
@ -878,6 +881,14 @@ const bodyFilterer = (( ) => {
static canFilter(fctxt, details) {
if ( µb.canFilterResponseData !== true ) { return; }
if ( (fctxt.itype & NOT_TEXT_TYPES) !== 0 ) { return; }
if ( fctxt.method !== fc.METHOD_GET ) {
if ( fctxt.method !== fc.METHOD_POST ) {
return;
}
}
// https://github.com/gorhill/uBlock/issues/3478
const statusCode = details.statusCode || 0;
if ( statusCode !== 0 && (statusCode < 200 || statusCode >= 300) ) {
@ -890,12 +901,14 @@ const bodyFilterer = (( ) => {
// https://bugzilla.mozilla.org/show_bug.cgi?id=1426789
const headers = details.responseHeaders;
const disposition = headerValueFromName('content-disposition', headers);
if ( disposition !== '' && disposition.startsWith('inline') === false ) {
return;
if ( disposition !== '' ) {
if ( disposition.startsWith('inline') === false ) {
return;
}
}
const contentType = headerValueFromName('content-type', headers);
let mime, charset;
let mime = 'text/plain', charset;
if ( contentType !== '' ) {
mime = mimeFromContentType(contentType);
if ( mime === undefined ) { return; }