mirror of
https://github.com/moodle/moodle.git
synced 2025-04-25 10:26:17 +02:00
MDL-25290 cache: Fixed issues with references when getting, and added unit tests to cover
This commit is contained in:
parent
26ce56fddf
commit
267ebe02b3
cache
22
cache/classes/loaders.php
vendored
22
cache/classes/loaders.php
vendored
@ -277,6 +277,13 @@ class cache implements cache_loader, cache_is_key_aware {
|
||||
if ($this->perfdebug) {
|
||||
cache_helper::record_cache_hit('** static persist **', $this->definition->get_id());
|
||||
}
|
||||
if (!is_scalar($result)) {
|
||||
// If data is an object it will be a reference.
|
||||
// If data is an array if may contain references.
|
||||
// We want to break references so that the cache cannot be modified outside of itself.
|
||||
// Call the function to unreference it (in the best way possible).
|
||||
$result = $this->unref($result);
|
||||
}
|
||||
return $result;
|
||||
} else if ($this->perfdebug) {
|
||||
cache_helper::record_cache_miss('** static persist **', $this->definition->get_id());
|
||||
@ -322,6 +329,15 @@ class cache implements cache_loader, cache_is_key_aware {
|
||||
if ($setaftervalidation) {
|
||||
$this->set($key, $result);
|
||||
}
|
||||
// 7. Make sure we don't pass back anything that could be a reference.
|
||||
// We don't want people modifying the data in the cache.
|
||||
if (!is_scalar($result)) {
|
||||
// If data is an object it will be a reference.
|
||||
// If data is an array if may contain references.
|
||||
// We want to break references so that the cache cannot be modified outside of itself.
|
||||
// Call the function to unreference it (in the best way possible).
|
||||
$result = $this->unref($result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -570,6 +586,12 @@ class cache implements cache_loader, cache_is_key_aware {
|
||||
foreach ($keyvaluearray as $key => $value) {
|
||||
if (is_object($value) && $value instanceof cacheable_object) {
|
||||
$value = new cache_cached_object($value);
|
||||
} else if (!is_scalar($value)) {
|
||||
// If data is an object it will be a reference.
|
||||
// If data is an array if may contain references.
|
||||
// We want to break references so that the cache cannot be modified outside of itself.
|
||||
// Call the function to unreference it (in the best way possible).
|
||||
$value = $this->unref($value);
|
||||
}
|
||||
if ($simulatettl) {
|
||||
$value = new cache_ttl_wrapper($value, $this->definition->get_ttl());
|
||||
|
17
cache/tests/cache_test.php
vendored
17
cache/tests/cache_test.php
vendored
@ -291,6 +291,23 @@ class cache_phpunit_tests extends advanced_testcase {
|
||||
$var = $cache->get('obj');
|
||||
$this->assertInstanceOf('stdClass', $var);
|
||||
$this->assertEquals('value', $var->key);
|
||||
|
||||
// Reference test after retrieve.
|
||||
$obj = new stdClass;
|
||||
$obj->key = 'value';
|
||||
$this->assertTrue($cache->set('obj', $obj));
|
||||
|
||||
$var1 = $cache->get('obj');
|
||||
$this->assertInstanceOf('stdClass', $var1);
|
||||
$this->assertEquals('value', $var1->key);
|
||||
$var1->key = 'eulav';
|
||||
$this->assertEquals('eulav', $var1->key);
|
||||
|
||||
$var2 = $cache->get('obj');
|
||||
$this->assertInstanceOf('stdClass', $var2);
|
||||
$this->assertEquals('value', $var2->key);
|
||||
|
||||
$this->assertTrue($cache->delete('obj'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user