Skip to content

Commit d4f01c3

Browse files
authored
Merge pull request #44 from iazaran/Dependabort-alerts-fixed
Dependabort alerts fixed
2 parents d114a08 + 511758a commit d4f01c3

6 files changed

Lines changed: 86 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to the `iazaran/smart-cache` package will be documented in t
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.12.1] - 2026-05-29
9+
### Security
10+
- Upgraded `symfony/mime` from `v8.0.8` to `v8.1.0` (>= patched line `8.0.12`) to address GHSA Email Header / SMTP Command Injection via CRLF in `Symfony\Component\Mime\Address` and Email Header Injection via Non-Token Characters in Mime Parameter Names. Transitive bumps: `symfony/deprecation-contracts` `v3.6.0``v3.7.0`, `symfony/polyfill-intl-idn` `v1.36.0``v1.38.1`, `symfony/polyfill-intl-normalizer` `v1.36.0``v1.38.0`, `symfony/polyfill-mbstring` `v1.36.0``v1.38.1`. No package API change.
11+
### Changed
12+
- `SmartCache::contentHash()` (Cache DNA write-deduplication hot path) now uses `xxh128` (PHP 8.1+, already a hard requirement) instead of `md5`. Output is still 32 lowercase hex characters, so the `_sc_dna:{key}` storage format is unchanged. Significantly faster on every `put()` when deduplication is enabled (default `true`). Existing `_sc_dna:*` entries from prior releases will mismatch once after upgrade and be transparently overwritten on the next `put()`; no errors, no data corruption.
13+
### Added
14+
- `tests/Unit/SmartCacheTest.php::test_cache_dna_hash_format_is_stable` locks the stored DNA hash contract (32 lowercase hex characters, deterministic for identical inputs, sensitive to value changes) so a future algorithm swap that breaks the key-length assumption is caught immediately.
15+
816
## [1.12.0] - 2026-05-21
917
### Fixed
1018
- `CompressionStrategy::restore()` now explicitly validates the `data` field, the base64 decode step, the `gzdecode()` decompression step, and the `unserialize()` step, throwing `RuntimeException` on any failure. Previously a corrupted compressed payload could surface as a silent PHP warning followed by a `false`/garbage return value, which the cache layer would then re-cache. The `unserialize()` call is now wrapped with a temporary error handler so corrupted payloads no longer leak `E_NOTICE` warnings into application logs (round-tripping the value `false` still works).

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ $users = SmartCache::get('users');
383383
## Testing
384384

385385
```bash
386-
composer test # 470 tests, 1,931 assertions
386+
composer test # 471 tests, 1,936 assertions
387387
composer test-coverage # with code coverage
388388
```
389389

composer.lock

Lines changed: 36 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2903,7 +2903,7 @@ <h2>Package Test Suite</h2>
29032903
<p>SmartCache ships with automated coverage for the Laravel-compatible API surface, optimization strategies, SWR patterns, invalidation, memoization, dashboard command execution, and large-data recovery behavior.</p>
29042904

29052905
<pre><code class="language-bash">composer test
2906-
# 470 tests, 1,931 assertions
2906+
# 471 tests, 1,936 assertions
29072907

29082908
vendor/bin/phpunit tests/Unit/Strategies/ChunkingStrategyTest.php --testdox
29092909
vendor/bin/phpunit tests/Unit/SmartCacheTest.php --filter "missing_chunk|self_healing" --testdox</code></pre>

src/SmartCache.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,12 +957,19 @@ public function persistCostMetadata(): void
957957
/**
958958
* Compute a fast content hash for write deduplication (Cache DNA).
959959
*
960+
* Uses `xxh128` (PHP 8.1+, guaranteed by the package's PHP requirement) which is
961+
* significantly faster than `md5` on typical payloads while producing the same
962+
* 32-character hex output. This is a non-cryptographic dedup check; collision
963+
* resistance is sufficient for distinguishing payload identity, and timing
964+
* comparisons here are not security-relevant because the hash is never an
965+
* authentication token.
966+
*
960967
* @param mixed $value
961968
* @return string
962969
*/
963970
protected function contentHash(mixed $value): string
964971
{
965-
return \md5(\serialize($value));
972+
return \hash('xxh128', \serialize($value));
966973
}
967974

968975
/**

tests/Unit/SmartCacheTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,38 @@ public function test_cache_dna_disabled_always_writes()
12091209
$this->assertNull($this->getCacheStore()->get("_sc_dna:{$key}"));
12101210
}
12111211

1212+
public function test_cache_dna_hash_format_is_stable()
1213+
{
1214+
// Locks the contract for the stored `_sc_dna:{key}` value:
1215+
// - 32 lowercase hex characters (same width as md5, drop-in compatible
1216+
// with any operator tooling that expects a fixed-width hash)
1217+
// - deterministic for identical inputs
1218+
// - sensitive to value changes (otherwise dedup would skip legitimate writes)
1219+
// Catches accidental algorithm swaps to a wider/narrower hash (e.g. sha256, crc32).
1220+
$this->app['config']->set('smart-cache.deduplication.enabled', true);
1221+
1222+
$smartCache = new SmartCache(
1223+
$this->getCacheStore(),
1224+
$this->getCacheManager(),
1225+
$this->app['config'],
1226+
);
1227+
1228+
$key = 'dna-format-key';
1229+
$smartCache->put($key, 'payload-A', 3600);
1230+
$hashA = $this->getCacheStore()->get("_sc_dna:{$key}");
1231+
1232+
$this->assertIsString($hashA);
1233+
$this->assertSame(32, \strlen($hashA));
1234+
$this->assertMatchesRegularExpression('/^[0-9a-f]{32}$/', $hashA);
1235+
1236+
$smartCache->forget($key);
1237+
$smartCache->put($key, 'payload-A', 3600);
1238+
$this->assertSame($hashA, $this->getCacheStore()->get("_sc_dna:{$key}"));
1239+
1240+
$smartCache->put($key, 'payload-B', 3600);
1241+
$this->assertNotSame($hashA, $this->getCacheStore()->get("_sc_dna:{$key}"));
1242+
}
1243+
12121244
// ---------------------------------------------------------------
12131245
// rememberIf (Conditional Caching) tests
12141246
// ---------------------------------------------------------------

0 commit comments

Comments
 (0)