fix: SnapshotStore verweigert nicht kodierbare Snapshots

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-16 17:33:03 +02:00
co-authored by Claude Haiku 5.5
parent 5ba52b98b3
commit 6ee8f9258a
2 changed files with 26 additions and 2 deletions
@@ -38,11 +38,16 @@ class SnapshotStore
/**
* @param array<array-key, mixed> $data The area's raw inventory.
* @throws SnapshotTooLarge
* @throws RuntimeException When the option could not be written.
* @throws RuntimeException When the snapshot cannot be encoded or the option could not be written.
*/
public function save(string $area, array $data, string $ability): string
{
$size = strlen((string) wp_json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$json = wp_json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (! is_string($json)) {
throw new RuntimeException(sprintf('snapshot %s could not be encoded', $area));
}
$size = strlen($json);
if ($size > self::MAX_BYTES) {
throw new SnapshotTooLarge($size);
}
@@ -87,6 +87,25 @@ final class SnapshotStoreTest extends TestCase
(new SnapshotStore())->save('presets', ['a' => 1], 'lit/divi-presets-set');
}
public function testAnUnencodableSnapshotIsRefusedBeforeAnyWrite(): void
{
Functions\when('wp_json_encode')->justReturn(false);
$written = false;
Functions\when('update_option')->alias(function () use (&$written): bool {
$written = true;
return true;
});
try {
(new SnapshotStore())->save('presets', ['a' => 1], 'lit/divi-presets-set');
self::fail('an unencodable snapshot must be refused');
} catch (RuntimeException $e) {
self::assertSame('snapshot presets could not be encoded', $e->getMessage());
}
self::assertFalse($written, 'nothing may be written when the snapshot cannot be encoded');
}
public function testCorruptOptionReadsAsEmpty(): void
{
$this->options['lit_mcp_snapshots_presets'] = 'kaputt';