See related thread: http://www.zenphoto.org/support/topic.php?id=3172&replies=1
[b]#2 Bypassing directory traversal[/b]
ZP scans the albums directory every time the script is executed. Since disk operations are expensive, we can try to limit disk-based I/O to make it load faster. We'll be using eAccelerator to cache our stuff, but you can easily adopt this code for APC, XCache, memcached or even a disk-file.
* Open class-album.php in zp-core directory.
* Put the following code at the beginning of the script:
`
function store_filenames_cache($dir, $has_dir, $pic_cache, $vid_cache) {
$cache_time_out = 600;
if ($has_dir) {
$pic_key = 'dp_' . md5($dir);
$vid_key = 'dv_' . md5($dir);
}
else {
$pic_key = 'fp_' . md5($dir);
$vid_key = 'fv_' . md5($dir);
}
$pic_val = serialize($pic_cache);
$vid_val = serialize($vid_cache);
eaccelerator_put($pic_key, $pic_val, $cache_time_out);
eaccelerator_put($vid_key, $vid_val, $cache_time_out);
}
function get_filenames_cache($dir, $has_dir, &$pic_cache, &$vid_cache) {
if ($has_dir) {
$pic_key = 'dp_' . md5($dir);
$vid_key = 'dv_' . md5($dir);
}
else {
$pic_key = 'fp_' . md5($dir);
$vid_key = 'fv_' . md5($dir);
}
$pic_cache = eaccelerator_get($pic_key);
$vid_cache = eaccelerator_get($vid_key);
if ( $pic_cache != NULL ) {
$pic_cache = unserialize($pic_cache);
}
else {
return FALSE;
}
if ( $vid_cache != NULL ) {
$vid_cache = unserialize($vid_cache);
}
else {
return FALSE;
}
return TRUE;
}
`
* Locate the loadFileNames() function, and replace it with this:
`
function loadFileNames($dirs=false) {
if ($this->isDynamic()) { // there are no 'real' files
return array();
}
$albumdir = getAlbumFolder() . $this->name . "/";
if (!is_dir($albumdir) || !is_readable($albumdir)) {
$msg = gettext("Error: The 'albums' directory")." (" . $this->albumdir . ") ";
if (!is_dir($this->albumdir)) {
$msg .= gettext("cannot be found.");
} else {
$msg .= gettext("is not readable.");
}
die($msg);
}
//masroore - cache these results
if (get_filenames_cache($albumdir, $dirs, $files, $videos) === FALSE) {
$dir = opendir($albumdir);
$files = array();
$videos = array();
while (false !== ($file = readdir($dir))) {
if ($dirs && (is_dir($albumdir.$file) && (substr($file, 0, 1) != '.') || hasDyanmicAlbumSuffix($file))) {
$files[] = $file;
} else if (!$dirs && is_file($albumdir.$file)) {
if (is_valid_video($file)) {
$files[] = $file;
$videos[] = $file;
} else if (is_valid_image($file)) {
$files[] = $file;
}
}
}
closedir($dir);
store_filenames_cache($albumdir, $dirs, $files, $videos);
}
if (count($videos) > 0) {
$video_thumbs = array();
foreach($videos as $video) {
$video_root = substr($video, 0, strrpos($video,"."));
foreach($files as $image) {
$image_root = substr($image, 0, strrpos($image,"."));
if ($image_root == $video_root && $image != $video) {
$video_thumbs[] = $image;
}
}
}
$files = array_diff($files, $video_thumbs);
}
return $files;
}
`