@fanboynz/network-scanner 2.0.47 → 2.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/adblock.js CHANGED
@@ -382,6 +382,7 @@ function createMatcher(rules, options = {}) {
382
382
  const urlCache = new URLCache(1000);
383
383
  let cacheHits = 0;
384
384
  let cacheMisses = 0;
385
+ const hasPartyRules = rules.thirdPartyRules.length > 0 || rules.firstPartyRules.length > 0;
385
386
 
386
387
  return {
387
388
  rules,
@@ -416,22 +417,21 @@ function createMatcher(rules, options = {}) {
416
417
  cacheMisses++;
417
418
  }
418
419
 
419
- // OPTIMIZATION #1: Only calculate third-party status if we have rules that need it
420
- const hasPartyRules = rules.thirdPartyRules.length > 0 || rules.firstPartyRules.length > 0;
421
- const isThirdParty = (sourceUrl && hasPartyRules)
422
- ? isThirdPartyRequest(url, sourceUrl)
423
- : false;
424
-
425
- // OPTIMIZATION #2: Calculate hostname parts once and reuse (avoid duplicate split operations)
420
+ // Calculate hostname parts once and reuse
426
421
  const hostnameParts = lowerHostname.split('.');
422
+
423
+ // Precompute parent domains once, reused for whitelist and block checks
424
+ const parentDomains = [];
425
+ const partsLen = hostnameParts.length;
426
+ for (let i = 1; i < partsLen; i++) {
427
+ parentDomains.push(hostnameParts.slice(i).join('.'));
428
+ }
427
429
 
428
- // V8 OPT: Extract and cache source page domain for $domain option checking
430
+ // Extract and cache source page domain for $domain and third-party checks
429
431
  let sourceDomain = null;
430
- let cachedSourceData = null;
431
432
 
432
433
  if (sourceUrl) {
433
- // Check if sourceUrl is in cache (avoid duplicate URL parsing)
434
- cachedSourceData = urlCache.get(sourceUrl);
434
+ const cachedSourceData = urlCache.get(sourceUrl);
435
435
 
436
436
  if (cachedSourceData) {
437
437
  sourceDomain = cachedSourceData.lowerHostname;
@@ -454,6 +454,11 @@ function createMatcher(rules, options = {}) {
454
454
  }
455
455
  }
456
456
 
457
+ // Calculate third-party status using already-parsed hostnames
458
+ const isThirdParty = (sourceDomain && hasPartyRules)
459
+ ? getBaseDomain(lowerHostname) !== getBaseDomain(sourceDomain)
460
+ : false;
461
+
457
462
  // === WHITELIST CHECK (exception rules take precedence) ===
458
463
 
459
464
  // Fast path: Check exact domain in Map (O(1))
@@ -468,10 +473,8 @@ function createMatcher(rules, options = {}) {
468
473
  }
469
474
 
470
475
  // Check parent domains for subdomain matches (e.g., sub.example.com -> example.com)
471
- const partsLen = hostnameParts.length; // V8: Cache array length
472
- for (let i = 1; i < partsLen; i++) {
473
- const parentDomain = hostnameParts.slice(i).join('.');
474
- rule = rules.whitelistMap.get(parentDomain); // V8: Single Map lookup
476
+ for (let i = 0; i < parentDomains.length; i++) {
477
+ rule = rules.whitelistMap.get(parentDomains[i]);
475
478
  if (rule) {
476
479
  if (enableLogging) {
477
480
  console.log(`[Adblock] Whitelisted: ${url} (${rule.raw})`);
@@ -508,9 +511,8 @@ function createMatcher(rules, options = {}) {
508
511
  }
509
512
 
510
513
  // Check parent domains for subdomain matches (e.g., ads.example.com -> example.com)
511
- for (let i = 1; i < partsLen; i++) { // V8: Reuse cached length
512
- const parentDomain = hostnameParts.slice(i).join('.');
513
- rule = rules.domainMap.get(parentDomain); // V8: Single Map lookup
514
+ for (let i = 0; i < parentDomains.length; i++) {
515
+ rule = rules.domainMap.get(parentDomains[i]);
514
516
  if (rule) {
515
517
  if (enableLogging) {
516
518
  console.log(`[Adblock] Blocked domain: ${url} (${rule.raw})`);
@@ -796,27 +798,6 @@ function matchesRule(rule, url, hostname, isThirdParty, resourceType, sourceDoma
796
798
  }
797
799
  }
798
800
 
799
- /**
800
- * Determine if request is third-party
801
- * @param {string} requestUrl - URL being requested
802
- * @param {string} sourceUrl - URL of the page making the request
803
- * @returns {boolean} True if third-party request
804
- */
805
- function isThirdPartyRequest(requestUrl, sourceUrl) {
806
- try {
807
- const requestHostname = new URL(requestUrl).hostname;
808
- const sourceHostname = new URL(sourceUrl).hostname;
809
-
810
- // Extract base domain (handle subdomains)
811
- const requestDomain = getBaseDomain(requestHostname);
812
- const sourceDomain = getBaseDomain(sourceHostname);
813
-
814
- return requestDomain !== sourceDomain;
815
- } catch (err) {
816
- return false;
817
- }
818
- }
819
-
820
801
  /**
821
802
  * Extract base domain from hostname
822
803
  * @param {string} hostname - Full hostname
@@ -833,6 +814,5 @@ function getBaseDomain(hostname) {
833
814
 
834
815
  module.exports = {
835
816
  parseAdblockRules,
836
- isThirdPartyRequest,
837
817
  getBaseDomain
838
818
  };
package/lib/grep.js CHANGED
@@ -3,9 +3,6 @@
3
3
 
4
4
  const fs = require('fs');
5
5
  const { spawnSync } = require('child_process');
6
- const crypto = require('crypto');
7
- const path = require('path');
8
- const os = require('os');
9
6
  const { colorize, colors, messageColors, tags, formatLogMessage } = require('./colorize');
10
7
 
11
8
  // === Constants ===
@@ -21,53 +18,9 @@ const GREP_DEFAULTS = {
21
18
  GREP_SUCCESS_STATUS: 0,
22
19
  GREP_NOT_FOUND_STATUS: 1,
23
20
  CURL_SUCCESS_STATUS: 0,
24
- VERSION_LINE_INDEX: 0,
25
- RANDOM_STRING_LENGTH: 9,
26
- TEMP_DIR_PREFIX: 'grep_search_'
21
+ VERSION_LINE_INDEX: 0
27
22
  };
28
23
 
29
- /**
30
- * Creates a temporary directory and file with content for grep processing
31
- * Uses mkdtempSync to avoid race conditions from filename collisions
32
- * @param {string} content - The content to write to temp file
33
- * @param {string} prefix - Prefix for temp filename
34
- * @returns {object} Object containing tempDir and tempFile paths
35
- */
36
- function createTempFile(content, prefix = 'scanner_grep') {
37
- const tempDir = os.tmpdir();
38
-
39
- // Create a unique temporary directory to avoid race conditions
40
- const uniqueTempDir = fs.mkdtempSync(path.join(tempDir, GREP_DEFAULTS.TEMP_DIR_PREFIX));
41
-
42
- // Use cryptographically secure random ID for additional uniqueness
43
- const uniqueId = crypto.randomBytes(8).toString('hex');
44
- const tempFile = path.join(uniqueTempDir, `${prefix}_${uniqueId}.tmp`);
45
-
46
- try {
47
- // Write atomically with error handling
48
- fs.writeFileSync(tempFile, content, {
49
- encoding: 'utf8',
50
- mode: 0o600 // Restrict permissions for security
51
- });
52
-
53
- return { tempDir: uniqueTempDir, tempFile };
54
- } catch (error) {
55
- // Clean up temp directory on write failure
56
- try {
57
- if (fs.existsSync(tempFile)) {
58
- fs.unlinkSync(tempFile);
59
- }
60
- if (fs.existsSync(uniqueTempDir)) {
61
- fs.rmdirSync(uniqueTempDir);
62
- }
63
- } catch (cleanupErr) {
64
- // Ignore cleanup errors, report original error
65
- }
66
-
67
- throw new Error(`Failed to create temp file: ${error.message}`);
68
- }
69
- }
70
-
71
24
  /**
72
25
  * Searches content using grep with the provided patterns
73
26
  * @param {string} content - The content to search
@@ -86,15 +39,8 @@ async function grepContent(content, searchPatterns, options = {}) {
86
39
  if (!content || searchPatterns.length === 0) {
87
40
  return { found: false, matchedPattern: null, allMatches: [] };
88
41
  }
89
-
90
- let tempFile = null;
91
- let tempDir = null;
92
-
42
+
93
43
  try {
94
- // Create temporary directory and file with content
95
- const tempResult = createTempFile(content, 'grep_search');
96
- tempDir = tempResult.tempDir;
97
- tempFile = tempResult.tempFile;
98
44
 
99
45
  const allMatches = [];
100
46
  let firstMatch = null;
@@ -111,12 +57,12 @@ async function grepContent(content, searchPatterns, options = {}) {
111
57
  if (wholeWord) grepArgs.push('-w');
112
58
  if (!regex) grepArgs.push('-F'); // Fixed strings (literal)
113
59
 
114
- // Add pattern and file
115
- grepArgs.push(pattern, tempFile);
60
+ grepArgs.push(pattern);
116
61
 
117
62
  try {
118
63
  const result = spawnSync('grep', grepArgs, {
119
64
  encoding: 'utf8',
65
+ input: content,
120
66
  timeout: GREP_DEFAULTS.GREP_TIMEOUT,
121
67
  maxBuffer: GREP_DEFAULTS.MAX_BUFFER_SIZE
122
68
  });
@@ -147,22 +93,6 @@ async function grepContent(content, searchPatterns, options = {}) {
147
93
 
148
94
  } catch (error) {
149
95
  throw new Error(`Grep search failed: ${error.message}`);
150
- } finally {
151
- // Clean up temporary file and directory
152
- if (tempFile) {
153
- try {
154
- fs.unlinkSync(tempFile);
155
- } catch (cleanupErr) {
156
- console.warn(formatLogMessage('warn', `[grep] Failed to cleanup temp file ${tempFile}: ${cleanupErr.message}`));
157
- }
158
- }
159
- if (tempDir) {
160
- try {
161
- fs.rmdirSync(tempDir);
162
- } catch (cleanupErr) {
163
- console.warn(formatLogMessage('warn', `[grep] Failed to cleanup temp directory ${tempDir}: ${cleanupErr.message}`));
164
- }
165
- }
166
96
  }
167
97
  }
168
98
 
@@ -418,6 +348,5 @@ module.exports = {
418
348
  grepContent,
419
349
  downloadAndGrep,
420
350
  createGrepHandler,
421
- validateGrepAvailability,
422
- createTempFile
351
+ validateGrepAvailability
423
352
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanboynz/network-scanner",
3
- "version": "2.0.47",
3
+ "version": "2.0.48",
4
4
  "description": "A Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features include fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, and multiple output formats.",
5
5
  "main": "nwss.js",
6
6
  "scripts": {