Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/private/Memcache/KeyValueCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,13 @@ private function normalizeTtl(int $ttl): int {
* Serialize a value for storage in the key-value store.
*/
protected static function encodeValue(mixed $value): string {
return is_int($value) ? (string)$value : json_encode($value, JSON_THROW_ON_ERROR);
return is_int($value) ? (string)$value : json_encode($value, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION);
}

/**
* Unserialize a value from the key-value store.
*/
protected static function decodeValue(string $value): mixed {
return is_numeric($value) ? (int)$value : json_decode($value, true);
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
return json_decode($value, true, flags: JSON_THROW_ON_ERROR);

}
}
4 changes: 2 additions & 2 deletions lib/private/Memcache/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,10 @@ protected function evalLua(string $scriptName, array $keys, array $args) {
}

protected static function encodeValue(mixed $value): string {
return is_int($value) ? (string)$value : json_encode($value);
return is_int($value) ? (string)$value : json_encode($value, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION);
}

protected static function decodeValue(string $value): mixed {
return is_numeric($value) ? (int)$value : json_decode($value, true);
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
return json_decode($value, true, flags: JSON_THROW_ON_ERROR);

}
}
43 changes: 43 additions & 0 deletions tests/lib/Memcache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,40 @@ abstract class Cache extends \Test\Cache\TestCache {
*/
protected $instance;

/**
* @return array<string, array{0: mixed}>
*/
public static function roundtripValuesProvider(): array {
return [
'string' => ['some string value'],
'empty string' => [''],
'numeric string' => ['0123'],
'float-like string' => ['3.14'],
'scientific notation string' => ['1e3'],
'integer' => [1234],
'zero' => [0],
'negative integer' => [-42],
'float' => [3.14],
'zero-fraction float' => [1.0],
'negative float' => [-2.75],
'scientific notation float' => [1.2e3],
'boolean true' => [true],
'boolean false' => [false],
'null' => [null],
'list' => [['a', 'b', 'c']],
'associative array' => [['foo' => 'bar', 'baz' => 42]],
'mixed nested array' => [[
'int' => 7,
'float' => 3.14,
'whole-float' => 1.0,
'string' => '3.14',
'bool' => true,
'null' => null,
'list' => [1, 2.5, '3'],
]],
];
}

public function testExistsAfterSet(): void {
$this->assertFalse($this->instance->hasKey('foo'));
$this->instance->set('foo', 'bar');
Expand All @@ -34,6 +68,15 @@ public function testGetArrayAfterSet(): void {
$this->assertEquals(['bar'], $this->instance->get('foo'));
}

#[\PHPUnit\Framework\Attributes\DataProvider('roundtripValuesProvider')]
public function testStoreAndReadBack(mixed $value): void {
$this->assertNull($this->instance->get('roundtrip'), 'key should be empty before storing');

$this->assertNotFalse($this->instance->set('roundtrip', $value), 'value should be stored');
$this->assertTrue($this->instance->hasKey('roundtrip'), 'stored key should exist');
$this->assertSame($value, $this->instance->get('roundtrip'), 'stored value should be read back unchanged');
}

public function testDoesNotExistAfterRemove(): void {
$this->instance->set('foo', 'bar');
$this->instance->remove('foo');
Expand Down
Loading