@@ -145,17 +145,24 @@ protected function getCacheKey(string $scope, string $value): string
145145        if  (!isset ($ this cacheKeys [$ scope$ value
146146            switch  ($ scope
147147                case  Constants::SCOPE_RANGE :
148-                     $ this -> cacheKeys [ $ scope ][ $ value ]  = Constants::SCOPE_IP  . self ::CACHE_SEP  . $ value
148+                     $ result SCOPE_IP  . self ::CACHE_SEP  . $ value
149149                    break ;
150150                case  Constants::SCOPE_IP :
151151                case  Constants::CACHE_TAG_GEO  . self ::CACHE_SEP  . Constants::SCOPE_IP :
152152                case  Constants::CACHE_TAG_CAPTCHA  . self ::CACHE_SEP  . Constants::SCOPE_IP :
153153                case  Constants::SCOPE_COUNTRY :
154-                     $ this -> cacheKeys [ $ scope ][ $ value ]  = $ scopeself ::CACHE_SEP  . $ value
154+                     $ result $ scopeself ::CACHE_SEP  . $ value
155155                    break ;
156156                default :
157157                    throw  new  BouncerException ('Unknown scope: '  . $ scope
158158            }
159+ 
160+             /** 
161+              * Replace unauthorized symbols. 
162+              * 
163+              * @see https://symfony.com/doc/current/components/cache/cache_items.html#cache-item-keys-and-values 
164+              */ 
165+             $ this cacheKeys [$ scope$ valuepreg_replace ('/[^A-Za-z0-9_.]/ ' , self ::CACHE_SEP , $ result
159166        }
160167
161168        return  $ this cacheKeys [$ scope$ value
@@ -285,7 +292,8 @@ protected function addRemediationToCacheItem(
285292        ]; // erase previous decision with the same id 
286293
287294        // Build the item lifetime in cache and sort remediations by priority 
288-         $ maxLifetimemax (array_column ($ remediations1 ));
295+         $ expsarray_column ($ remediations1 );
296+         $ maxLifetime$ expsmax ($ exps0 ;
289297        $ prioritizedRemediationssortRemediationByPriority ($ remediations
290298
291299        $ itemset ($ prioritizedRemediations
@@ -341,20 +349,14 @@ protected function defferUpdateCacheConfig(array $config): void
341349    protected  function  formatRemediationFromDecision (?array  $ decisionarray 
342350    {
343351        if  (!$ decision
344-             /** 
345-              * In stream mode we consider a clean IP forever... until the next resync. 
346-              * in this case, forever is 10 years as PHP_INT_MAX will cause trouble with the Memcached Adapter 
347-              * (int to float unwanted conversion) 
348-              * 
349-              */ 
350-             $ duration$ this streamMode  ? 315360000  : $ this cacheExpirationForCleanIp ;
352+             $ duration$ this cacheExpirationForCleanIp ;
351353
352354            return  [Constants::REMEDIATION_BYPASS , time () + $ duration0 ];
353355        }
354356
355357        $ durationself ::parseDurationToSeconds ($ decision'duration ' ]);
356358
357-         // Don't set a max duration in  stream mode to avoid bugs. Only  the stream update has to change the cache state. 
359+         // In  stream mode, only  the stream update has to change the cache state. 
358360        if  (!$ this streamMode ) {
359361            $ durationmin ($ this cacheExpirationForBadIp , $ duration
360362        }
@@ -425,6 +427,10 @@ protected function miss(string $value, string $cacheScope): string
425427                ]);
426428            }
427429        }
430+         // In stream mode, we do not save bypass decision in cache 
431+         if  ($ this streamMode  && !$ decisions
432+             return  Constants::REMEDIATION_BYPASS ;
433+         }
428434
429435        return  $ this saveRemediationsForCacheKey ($ decisions$ cacheKey
430436    }
@@ -464,7 +470,8 @@ protected function removeDecisionFromRemediationItem(string $cacheKey, int $deci
464470            return  true ;
465471        }
466472        // Build the item lifetime in cache and sort remediations by priority 
467-         $ maxLifetimemax (array_column ($ remediations1 ));
473+         $ expsarray_column ($ remediations1 );
474+         $ maxLifetime$ expsmax ($ exps0 ;
468475        $ cacheContentsortRemediationByPriority ($ remediations
469476        $ itemexpiresAt (new  DateTime ('@ '  . $ maxLifetime
470477        $ itemset ($ cacheContent
@@ -576,7 +583,8 @@ private function configureAdapter(): void
576583                    $ this adapter  = new  RedisTagAwareAdapter ((RedisAdapter::createConnection ($ redisDsn
577584                } catch  (Exception $ e
578585                    throw  new  BouncerException ('Error when connecting to Redis. '  .
579-                                                ' Please fix the Redis DSN or select another cache technology. ' );
586+                                                ' Please fix the Redis DSN or select another cache technology. '  .
587+                                                 ' Initial error was:  '  . $ egetMessage ());
580588                }
581589                break ;
582590
@@ -612,7 +620,7 @@ private static function parseDurationToSeconds(string $duration): int
612620        $ re'/(-?)(?:(?:(\d+)h)?(\d+)m)?(\d+).\d+(m?)s/m ' ;
613621        preg_match ($ re$ duration$ matches
614622        if  (!\count ($ matches
615-             throw  new  BouncerException (" Unable to parse the following duration:  $ { $ duration} . " 
623+             throw  new  BouncerException (' Unable to parse the following duration:  '  .  $ duration
616624        }
617625        $ seconds0 ;
618626        if  (isset ($ matches2 ])) {
@@ -621,12 +629,14 @@ private static function parseDurationToSeconds(string $duration): int
621629        if  (isset ($ matches3 ])) {
622630            $ secondsint )$ matches3 ]) * 60 ; // minutes 
623631        }
632+         $ secondsPart0 ;
624633        if  (isset ($ matches4 ])) {
625-             $ seconds int )$ matches4 ]); // seconds 
634+             $ secondsPart int )$ matches4 ]); // seconds 
626635        }
627636        if  ('m '  === ($ matches5 ])) { // units in milliseconds 
628-             $ seconds 0.001 ;
637+             $ secondsPart 0.001 ;
629638        }
639+         $ seconds$ secondsPart
630640        if  ('- '  === ($ matches1 ])) { // negative 
631641            $ seconds1 ;
632642        }
0 commit comments