0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2024-12-23 00:41:52 +00:00

Fix #49; prevent readdir infinite loop when cache directory not listable.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
This commit is contained in:
Edward Z. Yang 2016-03-27 14:53:31 -07:00
parent 91fd55c857
commit f14076dc3e
4 changed files with 29 additions and 1 deletions

2
NEWS
View File

@ -22,6 +22,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
- Support non-/tmp temporary directories for data:// validation - Support non-/tmp temporary directories for data:// validation
- Give a better error message when a user attempts to allow - Give a better error message when a user attempts to allow
ul/ol without allowing li. ul/ol without allowing li.
- On some versions of PHP, the Serializer DefinitionCache could
infinite loop when the directory exists but is not listable. (#49)
4.7.0, released 2015-08-04 4.7.0, released 2015-08-04
# opacity is now considered a "tricky" CSS property rather than a # opacity is now considered a "tricky" CSS property rather than a

View File

@ -118,7 +118,7 @@ abstract class HTMLPurifier_DefinitionCache
/** /**
* Clears all expired (older version or revision) objects from cache * Clears all expired (older version or revision) objects from cache
* @note Be carefuly implementing this method as flush. Flush must * @note Be careful implementing this method as flush. Flush must
* not interfere with other Definition types, and cleanup() * not interfere with other Definition types, and cleanup()
* should not be repeatedly called by userland code. * should not be repeatedly called by userland code.
* @param HTMLPurifier_Config $config * @param HTMLPurifier_Config $config

View File

@ -97,6 +97,12 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} }
$dir = $this->generateDirectoryPath($config); $dir = $this->generateDirectoryPath($config);
$dh = opendir($dir); $dh = opendir($dir);
// Apparently, on some versions of PHP, readdir will return
// an empty string if you pass an invalid argument to readdir.
// So you need this test. See #49.
if (false === $dh) {
return false;
}
while (false !== ($filename = readdir($dh))) { while (false !== ($filename = readdir($dh))) {
if (empty($filename)) { if (empty($filename)) {
continue; continue;
@ -106,6 +112,7 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} }
unlink($dir . '/' . $filename); unlink($dir . '/' . $filename);
} }
return true;
} }
/** /**
@ -119,6 +126,10 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} }
$dir = $this->generateDirectoryPath($config); $dir = $this->generateDirectoryPath($config);
$dh = opendir($dir); $dh = opendir($dir);
// See #49 (and above).
if (false === $dh) {
return false;
}
while (false !== ($filename = readdir($dh))) { while (false !== ($filename = readdir($dh))) {
if (empty($filename)) { if (empty($filename)) {
continue; continue;
@ -131,6 +142,7 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
unlink($dir . '/' . $filename); unlink($dir . '/' . $filename);
} }
} }
return true;
} }
/** /**

View File

@ -224,6 +224,20 @@ class HTMLPurifier_DefinitionCache_SerializerTest extends HTMLPurifier_Definitio
rmdir( $dir . '/Test'); rmdir( $dir . '/Test');
} }
public function testNoInfiniteLoop()
{
$cache = new HTMLPurifier_DefinitionCache_Serializer('Test');
$config = $this->generateConfigMock('serial');
$config->version = '1.0.0';
$config->returns('get', 1, array('Test.DefinitionRev'));
$dir = dirname(__FILE__) . '/SerializerTest';
$config->returns('get', $dir, array('Cache.SerializerPath'));
$config->returns('get', 0400, array('Cache.SerializerPermissions'));
$cache->cleanup($config);
}
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4