Skip to content

Commit

Permalink
Fixed a bug where cache files > 8192 bytes stored via stream wrappers…
Browse files Browse the repository at this point in the history
… would be truncated or empty (PEAR Bug #19422).
  • Loading branch information
coderbyheart committed May 21, 2012
1 parent 5916d41 commit 48f67b5
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 2 deletions.
8 changes: 6 additions & 2 deletions Cache/Lite.php
Expand Up @@ -729,9 +729,13 @@ function _read()
if ($this->_readControl) {
$hashControl = @fread($fp, 32);
$length = $length - 32;
}
}

if ($length) {
$data = @fread($fp, $length);
$data = '';
// See https://bugs.php.net/bug.php?id=30936
// The 8192 magic number is the chunk size used internally by PHP.
while(!feof($fp)) $data .= fread($fp, 8192);
} else {
$data = '';
}
Expand Down
30 changes: 30 additions & 0 deletions tests/PearBug19422Test.php
@@ -0,0 +1,30 @@
<?php

/**
* Test for CACHE_LITE_ERROR_DIE
*
* @package Cache_Lite
* @category Caching
* @version $Id$
* @author Markus Tacker <tacker@php.net>
*/

require_once 'tmpdir.inc';

class ErrorDieTest extends PHPUnit_Framework_TestCase
{
public function testErrorDie()
{
exec('/usr/bin/env php ' . __DIR__ . DIRECTORY_SEPARATOR . 'errordie.php', $out);
$message = join(PHP_EOL, $out);
$message = str_replace(tmpDir(), '<cachedir>/', $message); // Remove system specific cache dir
$expected = join(PHP_EOL, array(
'==> First call (cache should be missed)',
'Cache Missed !',
'0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Cache_Lite : Unable to write cache file : <cachedir>/31451992gjhgjh/cache_c21f969b5f03d33d43e04f8f136e7682_e9982ec5ca981bd365603623cf4b2277',
));

$this->assertEquals($message, $expected);

}
}
123 changes: 123 additions & 0 deletions tests/PearBug19422Test.phpt
@@ -0,0 +1,123 @@
--TEST--
Cache_Lite::Cache_Lite (PEAR bug #19422)
--FILE--
<?php

/**
* Test for Pear Bug #19422
*
* @see https://pear.php.net/bugs/bug.php?id=19422
* @see https://bugs.php.net/bug.php?id=30936
*
* @package Cache_Lite
* @category Caching
* @author Markus Tacker <tacker@php.net>
*/

require_once 'Cache/Lite.php';

define('FsStreamWrapper_CACHE_DIR', sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'cachelite-streamwrapper' . DIRECTORY_SEPARATOR);

class FsStreamWrapper
{
const SCHEME = 'public';
private $fp;

public function __construct()
{
if (!is_dir(FsStreamWrapper_CACHE_DIR)) mkdir(FsStreamWrapper_CACHE_DIR);
}

public function url_stat($path, $flags)
{
$localpath = $this->scheme2file($path);
if (!is_file($localpath)) return 0;
return stat($localpath);
}

private function scheme2file($path)
{
return str_replace(self::SCHEME . '://', FsStreamWrapper_CACHE_DIR, $path);
}

public function stream_open($path, $mode, $options, &$opath)
{
$this->fp = fopen($this->scheme2file($path), $mode);
return true;
}

public function stream_write($data)
{
return fwrite($this->fp, $data);
}

public function stream_close()
{
return fclose($this->fp);
}

public function stream_lock($operation)
{
return flock($this->fp, $operation);
}

public function unlink($path)
{
return unlink($this->scheme2file($path));
}

public function stream_read($count)
{
return fread($this->fp, $count);
}

public function stream_eof()
{
return feof($this->fp);
}

public function stream_seek($offset, $whence)
{
return !fseek($this->fp, $offset, $whence);
}

public function stream_flush()
{
return fflush($this->fp);
}

public function stream_tell()
{
return ftell($this->fp);
}

public function rename($from_uri, $to_uri)
{
return rename($this->scheme2file($from_uri), $this->scheme2file($to_uri));
}
}

$xml = array();
$cacheOpt = array();
$cacheOpt['cacheDir'] = 'public://';
$cacheOpt['cache_time'] = 3600;
$Cache_Lite = new Cache_Lite($cacheOpt);
$Cache_Lite->setToDebug();

stream_wrapper_register(FsStreamWrapper::SCHEME, 'FsStreamWrapper');

$fp = fopen('/dev/urandom', 'r');
$data = fread($fp, 32 * 1024);
fclose($fp);
$Cache_Lite->save($data, 'largechache');
$verify = $Cache_Lite->get('largechache');

var_dump(strlen($data) === strlen($verify));
var_dump($data === $verify);

?>
--GET--
--POST--
--EXPECT--
bool(true)
bool(true)

0 comments on commit 48f67b5

Please sign in to comment.