Bearsampp 2026.7.11
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 271 of file class.cache.php.

272 {
273 global $bearsamppRoot;
274
275 // Clear memory cache
276 self::$fileScanCache = null;
277
278 // Clear file caches
279 if (isset($bearsamppRoot)) {
280 $tmpPath = Path::getTmpPath();
281 $cacheFiles = glob($tmpPath . '/filescan_cache_*.dat');
282
283 if ($cacheFiles !== false) {
284 foreach ($cacheFiles as $cacheFile) {
285 @unlink($cacheFile);
286 }
287 Log::info('Cleared ' . count($cacheFiles) . ' file scan cache files');
288 }
289 }
290
291 // Reset stats
292 self::$fileScanStats = [
293 'hits' => 0,
294 'misses' => 0,
295 'invalidations' => 0
296 ];
297 }
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 229 of file class.cache.php.

230 {
232 // Bind the HMAC to the cache key so a valid payload for key A cannot
233 // be replayed under key B.
234 $message = json_encode($data) . $cacheKey;
235 return hash_hmac('sha256', $message, $key);
236 }
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 66 of file class.cache.php.

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

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

330 {
331 return self::$fileScanCacheDuration;
332 }

◆ getStats()

getStats ( )
static

Gets file scan cache statistics.

Returns
array Array containing hits, misses, and invalidations counts

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

305 {
306 return self::$fileScanStats;
307 }

◆ recordHit()

recordHit ( )
static

Records a cache hit for statistics tracking.

Returns
void

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

340 {
341 self::$fileScanStats['hits']++;
342 }

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 349 of file class.cache.php.

350 {
351 self::$fileScanStats['misses']++;
352 }

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 147 of file class.cache.php.

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

317 {
318 if ($seconds > 0 && $seconds <= 86400) { // Max 24 hours
319 self::$fileScanCacheDuration = $seconds;
320 Log::debug('File scan cache duration set to ' . $seconds . ' seconds');
321 }
322 }

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 246 of file class.cache.php.

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

References generateCacheHMAC().

Here is the call graph for this function:

Field Documentation

◆ $cacheIntegrityKey

$cacheIntegrityKey = null
staticprivate

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

◆ $fileScanCache

$fileScanCache = null
staticprivate

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

◆ $fileScanCacheDuration

$fileScanCacheDuration = 3600
staticprivate

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

◆ $fileScanStats

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

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


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