@@ -30,6 +30,7 @@ const CacheManager = (() => {
3030
3131 // Caches for allowed, blocked, and processing entries
3232 let allowedCaches = Object . create ( null ) ;
33+ let allowedPatternCaches = Object . create ( null ) ;
3334 let blockedCaches = Object . create ( null ) ;
3435 let processingCaches = Object . create ( null ) ;
3536
@@ -83,6 +84,7 @@ const CacheManager = (() => {
8384 // Initialize caches for each provider
8485 for ( const name of providers ) {
8586 allowedCaches [ name ] = new Map ( ) ;
87+ allowedPatternCaches [ name ] = new Set ( ) ;
8688 blockedCaches [ name ] = new Map ( ) ;
8789 processingCaches [ name ] = new Map ( ) ;
8890 }
@@ -114,9 +116,18 @@ const CacheManager = (() => {
114116 const entries = Object . entries ( callback [ name ] ) . filter ( ( [ key ] ) => ! DANGEROUS_KEYS . has ( key ) ) ;
115117
116118 blockedCaches [ name ] = new Map (
117- entries . map ( ( [ url , entry ] ) => [
118- url , { exp : entry . exp , resultType : entry . resultType }
119- ] )
119+ entries . flatMap ( ( [ url , { exp, resultType} ] ) => {
120+ if ( ! Number . isFinite ( exp ) && exp !== 0 || ! Number . isFinite ( resultType ) ) {
121+ console . warn ( `Skipping invalid blocked cache entry for "${ url } ": invalid exp or resultType` ) ;
122+ return [ ] ;
123+ }
124+
125+ if ( ! validResultTypes . has ( resultType ) ) {
126+ console . warn ( `Skipping blocked cache entry for "${ url } ": unrecognized resultType ${ resultType } ` ) ;
127+ return [ ] ;
128+ }
129+ return [ [ url , { exp, resultType} ] ] ;
130+ } )
120131 ) ;
121132 }
122133 }
@@ -129,8 +140,8 @@ const CacheManager = (() => {
129140 * @param {Object } [callback] The callback function to execute after loading the processing caches.
130141 */
131142 StorageUtil . getFromSessionStore ( processingKey , callback => {
132- for ( const name of Object . keys ( processingCaches ) ) {
133- if ( callback && typeof callback === 'object' ) {
143+ if ( callback && typeof callback === 'object' ) {
144+ for ( const name of Object . keys ( processingCaches ) ) {
134145 if ( callback [ name ] && typeof callback [ name ] === 'object' ) {
135146 const entries = Object . entries ( callback [ name ] ) . filter ( ( [ key ] ) => ! DANGEROUS_KEYS . has ( key ) ) ;
136147 processingCaches [ name ] = new Map ( entries ) ;
@@ -224,9 +235,18 @@ const CacheManager = (() => {
224235 }
225236 } ;
226237
227- cleanGroup ( allowedCaches , ( ) => updateLocalStorage ( ) ) ;
228- cleanGroup ( blockedCaches , ( ) => updateLocalStorage ( ) ) ;
238+ let localDirty = false ;
239+ cleanGroup ( allowedCaches , ( ) => {
240+ localDirty = true ;
241+ } ) ;
242+ cleanGroup ( blockedCaches , ( ) => {
243+ localDirty = true ;
244+ } ) ;
229245 cleanGroup ( processingCaches , ( ) => updateSessionStorage ( ) ) ;
246+
247+ if ( localDirty ) {
248+ updateLocalStorage ( ) ;
249+ }
230250 return totalRemoved ;
231251 } ;
232252
@@ -307,31 +327,6 @@ const CacheManager = (() => {
307327 return false ;
308328 } ;
309329
310- /**
311- * Checks if a string is in the allowed cache for a specific provider.
312- *
313- * @param {string } str The string to check.
314- * @param {string } name The name of the provider (e.g., "precisionSec").
315- * @returns {boolean } Returns true if the string is in the allowed cache and not expired, false otherwise.
316- */
317- const isStringInAllowedCache = ( str , name ) => {
318- try {
319- const map = allowedCaches [ name ] ;
320-
321- if ( ! map ) {
322- console . warn ( `Allowed cache "${ name } " not found` ) ;
323- return false ;
324- }
325-
326- if ( map . has ( str ) ) {
327- return true ;
328- }
329- } catch ( error ) {
330- console . error ( `Error checking allowed cache for string "${ str } ":` , error ) ;
331- }
332- return false ;
333- } ;
334-
335330 /**
336331 * Checks if a string is in the allowed cache for a specific provider.
337332 *
@@ -340,9 +335,13 @@ const CacheManager = (() => {
340335 * @returns {boolean } Returns true if the string is in the allowed cache and not expired, false otherwise.
341336 */
342337 const isPatternInAllowedCache = ( str , name ) => {
343- // Returns if the string is too long
344338 if ( typeof str !== 'string' || str . length > 2048 ) {
345- console . warn ( `Invalid string provided for allowed cache pattern check: "${ str } "` ) ;
339+ console . warn ( `Invalid string provided: "${ str } "` ) ;
340+ return false ;
341+ }
342+
343+ if ( name !== "all" && ! providersSet . has ( name ) ) {
344+ console . warn ( `Unknown cache provider name: "${ name } "` ) ;
346345 return false ;
347346 }
348347
@@ -354,16 +353,23 @@ const CacheManager = (() => {
354353 return false ;
355354 }
356355
357- // Checks if any key in the map (patterns, like *.example.com) matches the string
358- for ( const pattern of map . keys ( ) ) {
359- // Uses a simple pattern matching logic
360- if ( pattern . startsWith ( "*." ) ) {
361- const domain = pattern . slice ( 2 ) ;
356+ // O(1) exact-key check
357+ if ( map . has ( str ) ) {
358+ return true ;
359+ }
362360
363- if ( str === domain || str . endsWith ( "." + domain ) ) {
364- return true ;
365- }
366- } else if ( str === pattern ) {
361+ // O(1) wildcard pattern check for *.str
362+ if ( patternCache . has ( "*." + str ) ) {
363+ return true ;
364+ }
365+
366+ const dotIndex = str . indexOf ( "." ) ;
367+
368+ // O(n) wildcard pattern check for str with subdomains (e.g., sub.str)
369+ if ( dotIndex !== - 1 ) {
370+ const wildcardKey = "*." + str . slice ( dotIndex + 1 ) ;
371+
372+ if ( patternCache . has ( wildcardKey ) ) {
367373 return true ;
368374 }
369375 }
@@ -418,10 +424,20 @@ const CacheManager = (() => {
418424
419425 if ( name === "all" ) {
420426 for ( const cache of Object . values ( allowedCaches ) ) {
421- cache . set ( str , expTime ) ;
427+ cache . set ( str , 0 ) ;
428+ }
429+
430+ if ( str . startsWith ( "*." ) ) {
431+ for ( const patternCache of Object . values ( allowedPatternCaches ) ) {
432+ patternCache . add ( str ) ;
433+ }
422434 }
423435 } else if ( allowedCaches [ name ] ) {
424- allowedCaches [ name ] . set ( str , expTime ) ;
436+ allowedCaches [ name ] . set ( str , 0 ) ;
437+
438+ if ( str . startsWith ( "*." ) ) {
439+ allowedPatternCaches [ name ] . add ( str ) ;
440+ }
425441 } else {
426442 console . warn ( `Cache "${ name } " not found` ) ;
427443 }
@@ -489,11 +505,11 @@ const CacheManager = (() => {
489505 const cache = blockedCaches [ name ] ;
490506
491507 if ( name === "all" ) {
492- for ( const cache of Object . values ( blockedCaches ) ) {
493- cache . set ( key , { exp : expTime , resultType : resultType } ) ;
508+ for ( const providerCache of Object . values ( blockedCaches ) ) {
509+ providerCache . set ( key , { exp : expTime , resultType} ) ;
494510 }
495511 } else if ( cache ) {
496- cache . set ( key , { exp : expTime , resultType : resultType } ) ;
512+ cache . set ( key , { exp : expTime , resultType} ) ;
497513 } else {
498514 console . warn ( `Cache "${ name } " not found` ) ;
499515 }
@@ -530,16 +546,15 @@ const CacheManager = (() => {
530546
531547 if ( entry . exp > Date . now ( ) ) {
532548 return entry . resultType ;
533- } else {
534- // Entry expired, remove it
535- cache . delete ( key ) ;
536- updateLocalStorage ( ) ;
537549 }
550+
551+ // Entry expired, remove it
552+ cache . delete ( key ) ;
553+ updateLocalStorage ( ) ;
538554 } catch ( error ) {
539555 console . error ( `Error getting blocked result type for ${ url } :` , error ) ;
556+ console . warn ( `Returning default result type for ${ url } in provider "${ name } " due to error` ) ;
540557 }
541-
542- console . warn ( `Returning default result type for ${ url } in provider "${ name } " due to error or missing entry` ) ;
543558 return ProtectionResult . ResultType . FAILED ;
544559 } ;
545560
@@ -631,7 +646,7 @@ const CacheManager = (() => {
631646 }
632647
633648 const expTime = Date . now ( ) + 60 * 1000 ; // Expiration for processing cache is 60 seconds
634- const entry = { exp : expTime , tabId : tabId } ;
649+ const entry = { exp : expTime , tabId} ;
635650
636651 if ( name === "all" ) {
637652 for ( const cache of Object . values ( processingCaches ) ) {
@@ -680,41 +695,6 @@ const CacheManager = (() => {
680695 }
681696 } ;
682697
683- /**
684- * Retrieve all normalized-URL keys (or string keys) in the processing cache for a given provider
685- * that are associated with the specified tabId and not yet expired.
686- *
687- * @param {string } name The name of the provider (e.g., "precisionSec").
688- * @param {number } tabId The ID of the tab to filter by.
689- * @returns {string[] } An array of keys (normalized URLs or strings) that match the criteria.
690- */
691- const getKeysByTabId = ( name , tabId ) => {
692- const results = [ ] ;
693- const map = processingCaches [ name ] ;
694-
695- // Checks if the map is valid
696- if ( ! map ) {
697- console . warn ( `Processing cache "${ name } " not found` ) ;
698- return results ;
699- }
700-
701- const now = Date . now ( ) ;
702-
703- // Removes expired keys from the map
704- for ( const [ key , entry ] of map . entries ( ) ) {
705- if ( entry . tabId === tabId ) {
706- if ( entry . exp > now ) {
707- results . push ( key ) ;
708- } else {
709- map . delete ( key ) ;
710- }
711- }
712- }
713-
714- updateSessionStorage ( ) ;
715- return results ;
716- } ;
717-
718698 /**
719699 * Remove all entries in the processing cache for all keys associated with a specific tabId.
720700 *
@@ -726,18 +706,23 @@ const CacheManager = (() => {
726706 for ( const name of Object . keys ( processingCaches ) ) {
727707 const map = processingCaches [ name ] ;
728708
729- // Checks if the cache is valid
730709 if ( ! map ) {
731710 console . warn ( `Processing cache "${ name } " not found` ) ;
732711 continue ;
733712 }
734713
714+ const toRemove = [ ] ;
715+
735716 for ( const [ key , entry ] of map . entries ( ) ) {
736717 if ( entry . tabId === tabId ) {
737- removedCount ++ ;
738- map . delete ( key ) ;
718+ toRemove . push ( key ) ;
739719 }
740720 }
721+
722+ for ( const key of toRemove ) {
723+ map . delete ( key ) ;
724+ removedCount ++ ;
725+ }
741726 }
742727
743728 // Persist the changes to session storage
@@ -752,7 +737,6 @@ const CacheManager = (() => {
752737 clearBlockedCache,
753738 clearProcessingCache,
754739 isUrlInAllowedCache,
755- isStringInAllowedCache,
756740 isPatternInAllowedCache,
757741 addUrlToAllowedCache,
758742 addStringToAllowedCache,
@@ -763,8 +747,6 @@ const CacheManager = (() => {
763747 isUrlInProcessingCache,
764748 addUrlToProcessingCache,
765749 removeUrlFromProcessingCache,
766- getKeysByTabId,
767- removeKeysByTabId,
768- providers
750+ removeKeysByTabId
769751 } ) ;
770752} ) ( ) ;
0 commit comments