Bearsampp 2026.9.23
Loading...
Searching...
No Matches
Cache Class Reference

Static Public Member Functions

static clear ()
static get ($cacheKey)
static getDuration ()
static getStats ()
static recordHit ()
static recordMiss ()
static set ($cacheKey, $data)
static setDuration ($seconds)

Static Private Member Functions

static generateCacheHMAC ($data, $cacheKey)
static getCacheIntegrityKey ()
static verifyCacheIntegrity ($fileContents, $cacheKey)

Static Private Attributes

static $cacheIntegrityKey = null
static $fileScanCache = null
static $fileScanCacheDuration = 3600
static $fileScanStats

Detailed Description

Cache class for managing file scan caching with integrity verification.

This class handles caching of file scan results with optional integrity checks to prevent tampering. It supports both in-memory and file-based caching with configurable cache duration.

Usage Example:

$cached = Cache::get('my_cache_key');
if ($cached === false) {
$data = performExpensiveOperation();
Cache::set('my_cache_key', $data);
}
static set($cacheKey, $data)
static get($cacheKey)

Definition at line 27 of file class.cache.php.

Member Function Documentation

◆ clear()

clear ( )
static

Clears all file scan caches.

Returns
void

Definition at line 278 of file class.cache.php.

279 {
280 global $bearsamppRoot;
281
282 // Clear memory cache
283 self::$fileScanCache = null;
284
285 // Clear file caches
286 if (isset($bearsamppRoot)) {
287 $tmpPath = Path::getTmpPath();
288 $cacheFiles = glob($tmpPath . '/filescan_cache_*.dat');
289
290 if ($cacheFiles !== false) {
291 foreach ($cacheFiles as $cacheFile) {
292 @unlink($cacheFile);
293 }
294 Log::info('Cleared ' . count($cacheFiles) . ' file scan cache files');
295 }
296 }
297
298 // Reset stats
299 self::$fileScanStats = [
300 'hits' => 0,
301 'misses' => 0,
302 'invalidations' => 0
303 ];
304 }
global $bearsamppRoot
static info($data, $file=null)
static getTmpPath($aetrayPath=false)

References $bearsamppRoot, Path\getTmpPath(), and Log\info().

Here is the call graph for this function:

◆ generateCacheHMAC()

generateCacheHMAC ( $data,
$cacheKey )
staticprivate

Generates HMAC for cache data integrity verification.

Parameters
array$dataThe data to generate HMAC for
string$cacheKeyThe cache key
Returns
string The HMAC hash

Definition at line 235 of file class.cache.php.

236 {
238 // Bind the HMAC to the cache key so a valid payload for key A cannot
239 // be replayed under key B.
240 $message = json_encode($data) . $cacheKey;
241
242 return hash_hmac('sha256', $message, $key);
243 }
static getCacheIntegrityKey()

References getCacheIntegrityKey().

Referenced by set(), and verifyCacheIntegrity().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get()

get ( $cacheKey)
static

Gets cached file scan results if valid. Includes integrity verification to prevent cache tampering.

Parameters
string$cacheKeyThe cache key to retrieve.
Returns
array|false Returns cached results or false if cache is invalid/missing.

Definition at line 70 of file class.cache.php.

71 {
72 global $bearsamppRoot;
73
74 // Check if we have in-memory cache first
75 if (self::$fileScanCache !== null && isset(self::$fileScanCache[$cacheKey])) {
76 $cache = self::$fileScanCache[$cacheKey];
77
78 // Check if cache is still valid
79 if (time() - $cache['timestamp'] < self::$fileScanCacheDuration) {
80 return $cache['data'];
81 } else {
82 self::$fileScanStats['invalidations']++;
83 unset(self::$fileScanCache[$cacheKey]);
84 }
85 }
86
87 // Try to load from file cache
88 if (!isset($bearsamppRoot)) {
89 return false;
90 }
91
92 $cacheFile = Path::getTmpPath() . '/filescan_cache_' . $cacheKey . '.dat';
93
94 if (file_exists($cacheFile)) {
95 $fileContents = @file_get_contents($cacheFile);
96
97 if ($fileContents === false) {
98 return false;
99 }
100
101 // Verify HMAC over the raw file bytes BEFORE any parsing.
102 // This prevents PHP object injection via magic methods (__wakeup /
103 // __destruct) that would fire during unserialize() even when the
104 // HMAC subsequently fails.
105 if (!self::verifyCacheIntegrity($fileContents, $cacheKey)) {
106 Log::warning('File scan cache integrity check failed for key: ' . $cacheKey . '. Possible tampering detected.');
107 @unlink($cacheFile);
108
109 return false;
110 }
111
112 // Integrity confirmed – now it is safe to decode.
113 $cacheData = @json_decode($fileContents, true);
114
115 if (is_array($cacheData)
116 && isset($cacheData['timestamp']) && is_int($cacheData['timestamp'])
117 && isset($cacheData['data']) && is_array($cacheData['data'])
118 && isset($cacheData['hmac']) && is_string($cacheData['hmac'])
119 ) {
120 // Check if file cache is still valid
121 if (time() - $cacheData['timestamp'] < self::$fileScanCacheDuration) {
122 // Store in memory cache for faster subsequent access
123 if (self::$fileScanCache === null) {
124 self::$fileScanCache = [];
125 }
126 self::$fileScanCache[$cacheKey] = $cacheData;
127
128 return $cacheData['data'];
129 } else {
130 // Cache expired, delete file
131 self::$fileScanStats['invalidations']++;
132 @unlink($cacheFile);
133 }
134 } else {
135 // Invalid cache structure, delete file
136 Log::warning('Invalid cache structure detected for key: ' . $cacheKey);
137 @unlink($cacheFile);
138 }
139 }
140
141 return false;
142 }
static warning($data, $file=null)

References $bearsamppRoot, Path\getTmpPath(), and Log\warning().

Referenced by Util\getFilesToScan().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCacheIntegrityKey()

getCacheIntegrityKey ( )
staticprivate

Generates or retrieves the cache integrity key. This key is unique per session to prevent cross-session cache tampering.

Returns
string The cache integrity key

Definition at line 187 of file class.cache.php.

188 {
189 if (self::$cacheIntegrityKey === null) {
190 global $bearsamppRoot;
191
192 // Try to load existing key from session file
193 if (isset($bearsamppRoot)) {
194 $keyFile = Path::getTmpPath() . '/cache_integrity.key';
195
196 if (file_exists($keyFile)) {
197 $key = @file_get_contents($keyFile);
198 if ($key !== false && strlen($key) === 64) {
199 self::$cacheIntegrityKey = $key;
200
201 return self::$cacheIntegrityKey;
202 }
203 }
204
205 // Generate new key if none exists or invalid
206 try {
207 self::$cacheIntegrityKey = bin2hex(random_bytes(32));
208 @file_put_contents($keyFile, self::$cacheIntegrityKey, LOCK_EX);
209 } catch (Exception $e) {
210 Log::error('Failed to generate cache integrity key: ' . $e->getMessage());
211 // Fallback to a less secure but functional key
212 self::$cacheIntegrityKey = hash('sha256', uniqid('bearsampp_cache_', true));
213 }
214 } else {
215 // Fallback if bearsamppRoot not available
216 try {
217 self::$cacheIntegrityKey = bin2hex(random_bytes(32));
218 } catch (Exception $e) {
219 self::$cacheIntegrityKey = hash('sha256', uniqid('bearsampp_cache_', true));
220 }
221 }
222 }
223
224 return self::$cacheIntegrityKey;
225 }
static error($data, $file=null)

References $bearsamppRoot, Log\error(), and Path\getTmpPath().

Referenced by generateCacheHMAC().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getDuration()

getDuration ( )
static

Gets the current file scan cache duration.

Returns
int Cache duration in seconds

Definition at line 336 of file class.cache.php.

337 {
338 return self::$fileScanCacheDuration;
339 }

◆ getStats()

getStats ( )
static

Gets file scan cache statistics.

Returns
array Array containing hits, misses, and invalidations counts

Definition at line 311 of file class.cache.php.

312 {
313 return self::$fileScanStats;
314 }

◆ recordHit()

recordHit ( )
static

Records a cache hit for statistics tracking.

Returns
void

Definition at line 346 of file class.cache.php.

347 {
348 self::$fileScanStats['hits']++;
349 }

Referenced by Util\getFilesToScan().

Here is the caller graph for this function:

◆ recordMiss()

recordMiss ( )
static

Records a cache miss for statistics tracking.

Returns
void

Definition at line 356 of file class.cache.php.

357 {
358 self::$fileScanStats['misses']++;
359 }

Referenced by Util\getFilesToScan().

Here is the caller graph for this function:

◆ set()

set ( $cacheKey,
$data )
static

Stores file scan results in cache with integrity protection.

Parameters
string$cacheKeyThe cache key to store under.
array$dataThe scan results to cache.
Returns
void

Definition at line 152 of file class.cache.php.

153 {
154 global $bearsamppRoot;
155
156 // Generate HMAC for integrity verification
157 $hmac = self::generateCacheHMAC($data, $cacheKey);
158
159 $cacheData = [
160 'timestamp' => time(),
161 'data' => $data,
162 'hmac' => $hmac
163 ];
164
165 // Store in memory cache
166 if (self::$fileScanCache === null) {
167 self::$fileScanCache = [];
168 }
169 self::$fileScanCache[$cacheKey] = $cacheData;
170
171 // Store in file cache
172 if (isset($bearsamppRoot)) {
173 $cacheFile = Path::getTmpPath() . '/filescan_cache_' . $cacheKey . '.dat';
174 // JSON is used instead of serialize() to eliminate the PHP object-injection
175 // attack surface entirely – no magic methods can fire during json_decode().
176 @file_put_contents($cacheFile, json_encode($cacheData), LOCK_EX);
177 Log::debug('File scan results cached to: ' . $cacheFile);
178 }
179 }
static generateCacheHMAC($data, $cacheKey)
static debug($data, $file=null)

References $bearsamppRoot, Log\debug(), generateCacheHMAC(), and Path\getTmpPath().

Referenced by Util\getFilesToScan().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setDuration()

setDuration ( $seconds)
static

Sets the file scan cache duration.

Parameters
int$secondsCache duration in seconds (default: 3600 = 1 hour).
Returns
void

Definition at line 323 of file class.cache.php.

324 {
325 if ($seconds > 0 && $seconds <= 86400) { // Max 24 hours
326 self::$fileScanCacheDuration = $seconds;
327 Log::debug('File scan cache duration set to ' . $seconds . ' seconds');
328 }
329 }

References Log\debug().

Here is the call graph for this function:

◆ verifyCacheIntegrity()

verifyCacheIntegrity ( $fileContents,
$cacheKey )
staticprivate

Verifies cache file integrity using HMAC.

Parameters
string$fileContentsThe JSON-encoded cache file contents
string$cacheKeyThe cache key
Returns
bool True if integrity check passes, false otherwise

Definition at line 253 of file class.cache.php.

254 {
255 // Decode with json_decode() – unlike unserialize(), this cannot
256 // instantiate PHP objects or invoke any magic methods, so it is safe
257 // to call before the HMAC is confirmed.
258 $cacheData = @json_decode($fileContents, true);
259
260 if (!is_array($cacheData)
261 || !isset($cacheData['hmac']) || !is_string($cacheData['hmac'])
262 || !isset($cacheData['data']) || !is_array($cacheData['data'])
263 ) {
264 return false;
265 }
266
267 $expectedHmac = self::generateCacheHMAC($cacheData['data'], $cacheKey);
268
269 // Use hash_equals to prevent timing attacks
270 return hash_equals($expectedHmac, $cacheData['hmac']);
271 }

References generateCacheHMAC().

Here is the call graph for this function:

Field Documentation

◆ $cacheIntegrityKey

$cacheIntegrityKey = null
staticprivate

Definition at line 60 of file class.cache.php.

◆ $fileScanCache

$fileScanCache = null
staticprivate

Definition at line 34 of file class.cache.php.

◆ $fileScanCacheDuration

$fileScanCacheDuration = 3600
staticprivate

Definition at line 41 of file class.cache.php.

◆ $fileScanStats

$fileScanStats
staticprivate
Initial value:
= [
'hits' => 0,
'misses' => 0,
'invalidations' => 0
]

Definition at line 48 of file class.cache.php.


The documentation for this class was generated from the following file: