Chore: improve reject hosts robustness

This commit is contained in:
SukkaW
2023-12-07 20:39:52 +08:00
parent 2e3ef60ad3
commit 37b01ff016
3 changed files with 49 additions and 17 deletions

View File

@@ -5,8 +5,12 @@ import type { PublicSuffixList } from 'gorhill-publicsuffixlist';
const cache = createCache('cached-tld-parse', true); const cache = createCache('cached-tld-parse', true);
const sharedConfig = { allowPrivateDomains: true }; const sharedConfig = { allowPrivateDomains: true };
const sharedConfig2 = { allowPrivateDomains: true, detectIp: false };
/** { allowPrivateDomains: true } */
export const parse = (domain: string) => cache.sync(domain, () => tldts.parse(domain, sharedConfig)); export const parse = (domain: string) => cache.sync(domain, () => tldts.parse(domain, sharedConfig));
/** { allowPrivateDomains: true, detectIp: false } */
export const parse2 = (domain: string) => cache.sync(domain, () => tldts.parse(domain, sharedConfig2));
let gothillGetDomainCache: ReturnType<typeof createCache> | null = null; let gothillGetDomainCache: ReturnType<typeof createCache> | null = null;
export const createCachedGorhillGetDomain = (gorhill: PublicSuffixList) => { export const createCachedGorhillGetDomain = (gorhill: PublicSuffixList) => {

33
Build/lib/is-fast-ip.ts Normal file
View File

@@ -0,0 +1,33 @@
/**
* Check if a hostname is an IP. You should be aware that this only works
* because `hostname` is already garanteed to be a valid hostname!
*/
export function isProbablyIpv4(hostname: string): boolean {
// Cannot be shorted than 1.1.1.1
if (hostname.length < 7) {
return false;
}
// Cannot be longer than: 255.255.255.255
if (hostname.length > 15) {
return false;
}
let numberOfDots = 0;
for (let i = 0; i < hostname.length; i += 1) {
const code = hostname.charCodeAt(i);
if (code === 46 /* '.' */) {
numberOfDots += 1;
} else if (code < 48 /* '0' */ || code > 57 /* '9' */) {
return false;
}
}
return (
numberOfDots === 3
&& hostname.charCodeAt(0) !== 46
&& /* '.' */ hostname.charCodeAt(hostname.length - 1) !== 46 /* '.' */
);
}

View File

@@ -6,6 +6,7 @@ import { NetworkFilter } from '@cliqz/adblocker';
import { processLine } from './process-line'; import { processLine } from './process-line';
import { getGorhillPublicSuffixPromise } from './get-gorhill-publicsuffix'; import { getGorhillPublicSuffixPromise } from './get-gorhill-publicsuffix';
import type { PublicSuffixList } from 'gorhill-publicsuffixlist'; import type { PublicSuffixList } from 'gorhill-publicsuffixlist';
import { isProbablyIpv4 } from './is-fast-ip';
const DEBUG_DOMAIN_TO_FIND: string | null = null; // example.com | null const DEBUG_DOMAIN_TO_FIND: string | null = null; // example.com | null
let foundDebugDomain = false; let foundDebugDomain = false;
@@ -22,19 +23,16 @@ const warnOnce = (url: string, isWhite: boolean, ...message: any[]) => {
const normalizeDomain = (domain: string) => { const normalizeDomain = (domain: string) => {
if (!domain) return null; if (!domain) return null;
if (isProbablyIpv4(domain)) return null;
const parsed = tldts.parse(domain); const parsed = tldts.parse2(domain);
if (parsed.isIp) return null; if (parsed.isIp) return null;
if (!parsed.isIcann && !parsed.isPrivate) return null;
if (parsed.isIcann || parsed.isPrivate) { const h = parsed.hostname;
const h = parsed.hostname; if (!h) return null;
if (h === null) return null; return h[0] === '.' ? h.slice(1) : h;
return h[0] === '.' ? h.slice(1) : h;
}
return null;
}; };
export async function processDomainLists(domainListsUrl: string | URL, includeAllSubDomain = false) { export async function processDomainLists(domainListsUrl: string | URL, includeAllSubDomain = false) {
@@ -89,6 +87,7 @@ export async function processHosts(hostsUrl: string | URL, includeAllSubDomain =
} }
const domain = skipDomainCheck ? _domain : normalizeDomain(_domain); const domain = skipDomainCheck ? _domain : normalizeDomain(_domain);
if (domain) { if (domain) {
if (includeAllSubDomain) { if (includeAllSubDomain) {
domainSets.add(`.${domain}`); domainSets.add(`.${domain}`);
@@ -301,19 +300,15 @@ function parse($line: string, gorhill: PublicSuffixList): null | [hostname: stri
// && (!filter.isRegex()) // isPlain() === !isRegex() // && (!filter.isRegex()) // isPlain() === !isRegex()
&& (!filter.isFullRegex()) && (!filter.isFullRegex())
) { ) {
if (!gorhill.getDomain(filter.hostname)) {
return null;
}
const hostname = normalizeDomain(filter.hostname); const hostname = normalizeDomain(filter.hostname);
if (!hostname) { if (!hostname) {
console.log(' * [parse-filter E0000] invalid domain:', filter.hostname);
return null; return null;
} }
// console.log({ // |: filter.isHostnameAnchor(),
// '||': filter.isHostnameAnchor(), // |: filter.isLeftAnchor(),
// '|': filter.isLeftAnchor(), // |https://: !filter.isHostnameAnchor() && (filter.fromHttps() || filter.fromHttp())
// '|https://': !filter.isHostnameAnchor() && (filter.fromHttps() || filter.fromHttp())
// });
const isIncludeAllSubDomain = filter.isHostnameAnchor(); const isIncludeAllSubDomain = filter.isHostnameAnchor();
if (filter.isException() || filter.isBadFilter()) { if (filter.isException() || filter.isBadFilter()) {