implemented JSON file conversion on purge and storage in PHP files for data leak protection
This commit is contained in:
parent
577586c47f
commit
4f06feef81
10 changed files with 127 additions and 136 deletions
|
@ -22,6 +22,13 @@ use PDO;
|
||||||
*/
|
*/
|
||||||
class Configuration
|
class Configuration
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* First line in INI file, to hide contents
|
||||||
|
*
|
||||||
|
* @const string
|
||||||
|
*/
|
||||||
|
const PROTECTION_LINE = ';<?php http_response_code(403); /*' . PHP_EOL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parsed configuration
|
* parsed configuration
|
||||||
*
|
*
|
||||||
|
@ -105,24 +112,27 @@ class Configuration
|
||||||
|
|
||||||
// rename INI files to avoid configuration leakage
|
// rename INI files to avoid configuration leakage
|
||||||
if (is_readable($configIni)) {
|
if (is_readable($configIni)) {
|
||||||
|
$context = stream_context_create();
|
||||||
// don't overwrite already converted file
|
// don't overwrite already converted file
|
||||||
if (!is_file($configFile)) {
|
if (!is_file($configFile)) {
|
||||||
$iniHandle = fopen($configIni, 'r', false, stream_context_create());
|
$iniHandle = fopen($configIni, 'r', false, $context);
|
||||||
$written = file_put_contents($configFile, ';<?php http_response_code(403); /*' . PHP_EOL);
|
file_put_contents($configFile, self::PROTECTION_LINE);
|
||||||
$written = file_put_contents($configFile, $iniHandle, FILE_APPEND);
|
file_put_contents($configFile, $iniHandle, FILE_APPEND);
|
||||||
fclose($iniHandle);
|
fclose($iniHandle);
|
||||||
unlink($configIni);
|
|
||||||
}
|
}
|
||||||
|
unlink($configIni);
|
||||||
|
|
||||||
// cleanup sample, too
|
// cleanup sample, too
|
||||||
$configSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php';
|
$configSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php';
|
||||||
$configIniSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample';
|
$configIniSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample';
|
||||||
if (is_readable($configIniSample)) {
|
if (is_readable($configIniSample)) {
|
||||||
if (is_readable($configSample)) {
|
if (!is_readable($configSample)) {
|
||||||
unlink($configIniSample);
|
$iniSampleHandle = fopen($configIniSample, 'r', false, $context);
|
||||||
} else {
|
file_put_contents($configSample, self::PROTECTION_LINE);
|
||||||
rename($configIniSample, $configSample);
|
file_put_contents($configSample, $iniSampleHandle, FILE_APPEND);
|
||||||
|
fclose($iniSampleHandle);
|
||||||
}
|
}
|
||||||
|
unlink($configIniSample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Filesystem extends AbstractData
|
||||||
public function create($pasteid, $paste)
|
public function create($pasteid, $paste)
|
||||||
{
|
{
|
||||||
$storagedir = self::_dataid2path($pasteid);
|
$storagedir = self::_dataid2path($pasteid);
|
||||||
$file = $storagedir . $pasteid;
|
$file = $storagedir . $pasteid . '.php';
|
||||||
if (is_file($file)) {
|
if (is_file($file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,7 @@ class Filesystem extends AbstractData
|
||||||
if (!$this->exists($pasteid)) {
|
if (!$this->exists($pasteid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$paste = json_decode(
|
$paste = self::_decodeFile(self::_dataid2path($pasteid) . $pasteid . '.php');
|
||||||
file_get_contents(self::_dataid2path($pasteid) . $pasteid)
|
|
||||||
);
|
|
||||||
if (property_exists($paste->meta, 'attachment')) {
|
if (property_exists($paste->meta, 'attachment')) {
|
||||||
$paste->attachment = $paste->meta->attachment;
|
$paste->attachment = $paste->meta->attachment;
|
||||||
unset($paste->meta->attachment);
|
unset($paste->meta->attachment);
|
||||||
|
@ -104,8 +102,8 @@ class Filesystem extends AbstractData
|
||||||
$pastedir = self::_dataid2path($pasteid);
|
$pastedir = self::_dataid2path($pasteid);
|
||||||
if (is_dir($pastedir)) {
|
if (is_dir($pastedir)) {
|
||||||
// Delete the paste itself.
|
// Delete the paste itself.
|
||||||
if (is_file($pastedir . $pasteid)) {
|
if (is_file($pastedir . $pasteid . '.php')) {
|
||||||
unlink($pastedir . $pasteid);
|
unlink($pastedir . $pasteid . '.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete discussion if it exists.
|
// Delete discussion if it exists.
|
||||||
|
@ -133,7 +131,41 @@ class Filesystem extends AbstractData
|
||||||
*/
|
*/
|
||||||
public function exists($pasteid)
|
public function exists($pasteid)
|
||||||
{
|
{
|
||||||
return is_file(self::_dataid2path($pasteid) . $pasteid);
|
$basePath = self::_dataid2path($pasteid) . $pasteid;
|
||||||
|
$pastePath = $basePath . '.php';
|
||||||
|
// convert to PHP protected files if needed
|
||||||
|
if (is_readable($basePath)) {
|
||||||
|
$context = stream_context_create();
|
||||||
|
// don't overwrite already converted file
|
||||||
|
if (!is_file($pastePath)) {
|
||||||
|
$handle = fopen($basePath, 'r', false, $context);
|
||||||
|
file_put_contents($pastePath, DataStore::PROTECTION_LINE . PHP_EOL);
|
||||||
|
file_put_contents($pastePath, $handle, FILE_APPEND);
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
unlink($basePath);
|
||||||
|
|
||||||
|
// convert comments, too
|
||||||
|
$discdir = self::_dataid2discussionpath($pasteid);
|
||||||
|
if (is_dir($discdir)) {
|
||||||
|
$dir = dir($discdir);
|
||||||
|
while (false !== ($filename = $dir->read())) {
|
||||||
|
if (substr($filename, -4) !== '.php' && strlen($filename) >= 16) {
|
||||||
|
$commentFilename = $discdir . $filename . '.php';
|
||||||
|
// don't overwrite already converted file
|
||||||
|
if (!is_file($commentFilename)) {
|
||||||
|
$handle = fopen($discdir . $filename, 'r', false, $context);
|
||||||
|
file_put_contents($commentFilename, DataStore::PROTECTION_LINE . PHP_EOL);
|
||||||
|
file_put_contents($commentFilename, $handle, FILE_APPEND);
|
||||||
|
fclose($handle);
|
||||||
|
}
|
||||||
|
unlink($discdir . $filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dir->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is_readable($pastePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,7 +181,7 @@ class Filesystem extends AbstractData
|
||||||
public function createComment($pasteid, $parentid, $commentid, $comment)
|
public function createComment($pasteid, $parentid, $commentid, $comment)
|
||||||
{
|
{
|
||||||
$storagedir = self::_dataid2discussionpath($pasteid);
|
$storagedir = self::_dataid2discussionpath($pasteid);
|
||||||
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid;
|
$file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid . '.php';
|
||||||
if (is_file($file)) {
|
if (is_file($file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -171,15 +203,14 @@ class Filesystem extends AbstractData
|
||||||
$comments = array();
|
$comments = array();
|
||||||
$discdir = self::_dataid2discussionpath($pasteid);
|
$discdir = self::_dataid2discussionpath($pasteid);
|
||||||
if (is_dir($discdir)) {
|
if (is_dir($discdir)) {
|
||||||
// Delete all files in discussion directory
|
|
||||||
$dir = dir($discdir);
|
$dir = dir($discdir);
|
||||||
while (false !== ($filename = $dir->read())) {
|
while (false !== ($filename = $dir->read())) {
|
||||||
// Filename is in the form pasteid.commentid.parentid:
|
// Filename is in the form pasteid.commentid.parentid.php:
|
||||||
// - pasteid is the paste this reply belongs to.
|
// - pasteid is the paste this reply belongs to.
|
||||||
// - commentid is the comment identifier itself.
|
// - commentid is the comment identifier itself.
|
||||||
// - parentid is the comment this comment replies to (It can be pasteid)
|
// - parentid is the comment this comment replies to (It can be pasteid)
|
||||||
if (is_file($discdir . $filename)) {
|
if (is_file($discdir . $filename)) {
|
||||||
$comment = json_decode(file_get_contents($discdir . $filename));
|
$comment = self::_decodeFile($discdir . $filename);
|
||||||
$items = explode('.', $filename);
|
$items = explode('.', $filename);
|
||||||
// Add some meta information not contained in file.
|
// Add some meta information not contained in file.
|
||||||
$comment->id = $items[1];
|
$comment->id = $items[1];
|
||||||
|
@ -211,7 +242,7 @@ class Filesystem extends AbstractData
|
||||||
{
|
{
|
||||||
return is_file(
|
return is_file(
|
||||||
self::_dataid2discussionpath($pasteid) .
|
self::_dataid2discussionpath($pasteid) .
|
||||||
$pasteid . '.' . $commentid . '.' . $parentid
|
$pasteid . '.' . $commentid . '.' . $parentid . '.php'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +284,14 @@ class Filesystem extends AbstractData
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$thirdLevel = array_filter(
|
$thirdLevel = array_filter(
|
||||||
scandir($path),
|
array_map(
|
||||||
|
function($filename) {
|
||||||
|
return strlen($filename) >= 20 ?
|
||||||
|
substr($filename, 0, -4) :
|
||||||
|
$filename;
|
||||||
|
},
|
||||||
|
scandir($path)
|
||||||
|
),
|
||||||
'PrivateBin\\Model\\Paste::isValidId'
|
'PrivateBin\\Model\\Paste::isValidId'
|
||||||
);
|
);
|
||||||
if (count($thirdLevel) == 0) {
|
if (count($thirdLevel) == 0) {
|
||||||
|
@ -347,4 +385,17 @@ class Filesystem extends AbstractData
|
||||||
{
|
{
|
||||||
return (bool) preg_match('/^[a-f0-9]{2}$/', $element);
|
return (bool) preg_match('/^[a-f0-9]{2}$/', $element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a paste or comment file.
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @param string $file
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function _decodeFile($file)
|
||||||
|
{
|
||||||
|
return json_decode(substr(file_get_contents($file), strlen(DataStore::PROTECTION_LINE . PHP_EOL)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,13 @@ use PrivateBin\Json;
|
||||||
*/
|
*/
|
||||||
class DataStore extends AbstractPersistence
|
class DataStore extends AbstractPersistence
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* First line in JSON files, to hide contents
|
||||||
|
*
|
||||||
|
* @const string
|
||||||
|
*/
|
||||||
|
const PROTECTION_LINE = '<?php http_response_code(403); /*';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* store the data
|
* store the data
|
||||||
*
|
*
|
||||||
|
@ -38,7 +45,7 @@ class DataStore extends AbstractPersistence
|
||||||
$filename = substr($filename, strlen($path));
|
$filename = substr($filename, strlen($path));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
self::_store($filename, Json::encode($data));
|
self::_store($filename, self::PROTECTION_LINE . PHP_EOL . Json::encode($data));
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -14,8 +14,8 @@ if (!defined('PATH')) {
|
||||||
if (!defined('CONF')) {
|
if (!defined('CONF')) {
|
||||||
define('CONF', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php');
|
define('CONF', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php');
|
||||||
}
|
}
|
||||||
if (!is_file(CONF)) {
|
if (!defined('CONF_SAMPLE')) {
|
||||||
copy(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php', CONF);
|
define('CONF_SAMPLE', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
require PATH . 'vendor/autoload.php';
|
require PATH . 'vendor/autoload.php';
|
||||||
|
@ -203,6 +203,9 @@ class Helper
|
||||||
if (!is_file(CONF . '.bak') && is_file(CONF)) {
|
if (!is_file(CONF . '.bak') && is_file(CONF)) {
|
||||||
rename(CONF, CONF . '.bak');
|
rename(CONF, CONF . '.bak');
|
||||||
}
|
}
|
||||||
|
if (!is_file(CONF_SAMPLE . '.bak') && is_file(CONF_SAMPLE)) {
|
||||||
|
copy(CONF_SAMPLE, CONF_SAMPLE . '.bak');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -215,6 +218,9 @@ class Helper
|
||||||
if (is_file(CONF . '.bak')) {
|
if (is_file(CONF . '.bak')) {
|
||||||
rename(CONF . '.bak', CONF);
|
rename(CONF . '.bak', CONF);
|
||||||
}
|
}
|
||||||
|
if (is_file(CONF_SAMPLE . '.bak')) {
|
||||||
|
rename(CONF_SAMPLE . '.bak', CONF_SAMPLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,12 +22,14 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
{
|
{
|
||||||
/* Tear Down Routine */
|
/* Tear Down Routine */
|
||||||
|
if (is_file(CONF)) {
|
||||||
|
unlink(CONF);
|
||||||
|
}
|
||||||
Helper::confRestore();
|
Helper::confRestore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDefaultConfigFile()
|
public function testDefaultConfigFile()
|
||||||
{
|
{
|
||||||
$this->assertTrue(copy(CONF . '.bak', CONF), 'copy default configuration file');
|
|
||||||
$conf = new Configuration;
|
$conf = new Configuration;
|
||||||
$this->assertEquals($this->_options, $conf->get(), 'default configuration is correct');
|
$this->assertEquals($this->_options, $conf->get(), 'default configuration is correct');
|
||||||
}
|
}
|
||||||
|
@ -41,7 +43,9 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testHandleMissingConfigFile()
|
public function testHandleMissingConfigFile()
|
||||||
{
|
{
|
||||||
@unlink(CONF);
|
if (is_file(CONF)) {
|
||||||
|
unlink(CONF);
|
||||||
|
}
|
||||||
$conf = new Configuration;
|
$conf = new Configuration;
|
||||||
$this->assertEquals($this->_options, $conf->get(), 'returns correct defaults on missing file');
|
$this->assertEquals($this->_options, $conf->get(), 'returns correct defaults on missing file');
|
||||||
}
|
}
|
||||||
|
@ -161,16 +165,16 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||||
public function testRenameIniSample()
|
public function testRenameIniSample()
|
||||||
{
|
{
|
||||||
$iniSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample';
|
$iniSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini.sample';
|
||||||
$phpSample = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php';
|
|
||||||
|
|
||||||
Helper::createIniFile(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', $this->_options);
|
Helper::createIniFile(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', $this->_options);
|
||||||
if (is_file(CONF)) {
|
if (is_file(CONF)) {
|
||||||
chmod(CONF, 0600);
|
|
||||||
unlink(CONF);
|
unlink(CONF);
|
||||||
}
|
}
|
||||||
rename($phpSample, $iniSample);
|
rename(CONF_SAMPLE, $iniSample);
|
||||||
new Configuration;
|
new Configuration;
|
||||||
$this->assertFileNotExists($iniSample, 'old sample file gets removed');
|
$this->assertFileNotExists($iniSample, 'old sample file gets removed');
|
||||||
$this->assertFileExists($phpSample, 'new sample file gets created');
|
$this->assertFileExists(CONF_SAMPLE, 'new sample file gets created');
|
||||||
|
$this->assertFileExists(CONF, 'old configuration file gets converted');
|
||||||
|
$this->assertFileNotExists(PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini', 'old configuration file gets removed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,13 +163,16 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||||
$this->assertFileExists($storagedir . $dataid . '.php', "paste $dataid exists in new format");
|
$this->assertFileExists($storagedir . $dataid . '.php', "paste $dataid exists in new format");
|
||||||
$this->assertFileNotExists($storagedir . $dataid, "old format paste $dataid got removed");
|
$this->assertFileNotExists($storagedir . $dataid, "old format paste $dataid got removed");
|
||||||
$this->assertTrue($this->_model->exists($dataid), "paste $dataid exists");
|
$this->assertTrue($this->_model->exists($dataid), "paste $dataid exists");
|
||||||
$this->assertEquals($this->_model->read($dataid), $paste, "paste $dataid wasn't modified in the conversion");
|
$this->assertEquals($this->_model->read($dataid), json_decode(json_encode($paste)), "paste $dataid wasn't modified in the conversion");
|
||||||
|
|
||||||
$storagedir .= $dataid . '.discussion' . DIRECTORY_SEPARATOR;
|
$storagedir .= $dataid . '.discussion' . DIRECTORY_SEPARATOR;
|
||||||
$this->assertFileExists($storagedir . $dataid . '.' . $commentid . '.' . $dataid . '.php', "comment of $dataid exists in new format");
|
$this->assertFileExists($storagedir . $dataid . '.' . $commentid . '.' . $dataid . '.php', "comment of $dataid exists in new format");
|
||||||
$this->assertFileNotExists($storagedir . $dataid . '.' . $commentid . '.' . $dataid, "old format comment of $dataid got removed");
|
$this->assertFileNotExists($storagedir . $dataid . '.' . $commentid . '.' . $dataid, "old format comment of $dataid got removed");
|
||||||
$this->assertTrue($this->_model->existsComment($dataid, $dataid, $commentid), "comment in paste $dataid exists");
|
$this->assertTrue($this->_model->existsComment($dataid, $dataid, $commentid), "comment in paste $dataid exists");
|
||||||
$this->assertEquals($this->_model->readComment($dataid, $dataid, $commentid), $comment, "comment of $dataid wasn't modified in the conversion");
|
$comment = json_decode(json_encode($comment));
|
||||||
|
$comment->id = $commentid;
|
||||||
|
$comment->parentid = $dataid;
|
||||||
|
$this->assertEquals($this->_model->readComments($dataid), array($comment->meta->postdate => $comment), "comment of $dataid wasn't modified in the conversion");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,30 +14,17 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
/* Setup Routine */
|
/* Setup Routine */
|
||||||
Helper::confBackup();
|
|
||||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||||
ServerSalt::setPath($this->_path);
|
ServerSalt::setPath($this->_path);
|
||||||
$this->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function tearDown()
|
|
||||||
{
|
|
||||||
/* Tear Down Routine */
|
|
||||||
Helper::confRestore();
|
|
||||||
Helper::rmDir($this->_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reset()
|
|
||||||
{
|
|
||||||
$_POST = array();
|
$_POST = array();
|
||||||
$_GET = array();
|
$_GET = array();
|
||||||
$_SERVER = array();
|
$_SERVER = array();
|
||||||
if ($this->_model->exists(Helper::getPasteId())) {
|
if ($this->_model->exists(Helper::getPasteId())) {
|
||||||
$this->_model->delete(Helper::getPasteId());
|
$this->_model->delete(Helper::getPasteId());
|
||||||
}
|
}
|
||||||
Helper::confRestore();
|
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||||
$options = parse_ini_file(CONF, true);
|
|
||||||
$options['purge']['dir'] = $this->_path;
|
$options['purge']['dir'] = $this->_path;
|
||||||
$options['traffic']['dir'] = $this->_path;
|
$options['traffic']['dir'] = $this->_path;
|
||||||
$options['model_options']['dir'] = $this->_path;
|
$options['model_options']['dir'] = $this->_path;
|
||||||
|
@ -45,15 +32,21 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function tearDown()
|
||||||
|
{
|
||||||
|
/* Tear Down Routine */
|
||||||
|
unlink(CONF);
|
||||||
|
Helper::confRestore();
|
||||||
|
Helper::rmDir($this->_path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @runInSeparateProcess
|
* @runInSeparateProcess
|
||||||
*/
|
*/
|
||||||
public function testCreate()
|
public function testCreate()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
|
@ -80,10 +73,8 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testPut()
|
public function testPut()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$paste = Helper::getPaste();
|
$paste = Helper::getPaste();
|
||||||
unset($paste['meta']);
|
unset($paste['meta']);
|
||||||
|
@ -117,7 +108,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDelete()
|
public function testDelete()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||||
$paste = $this->_model->read(Helper::getPasteId());
|
$paste = $this->_model->read(Helper::getPasteId());
|
||||||
|
@ -144,7 +134,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteWithPost()
|
public function testDeleteWithPost()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||||
$paste = $this->_model->read(Helper::getPasteId());
|
$paste = $this->_model->read(Helper::getPasteId());
|
||||||
|
@ -168,7 +157,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testRead()
|
public function testRead()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$paste['meta']['attachment'] = $paste['attachment'];
|
$paste['meta']['attachment'] = $paste['attachment'];
|
||||||
$paste['meta']['attachmentname'] = $paste['attachmentname'];
|
$paste['meta']['attachmentname'] = $paste['attachmentname'];
|
||||||
|
@ -200,7 +188,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testJsonLdPaste()
|
public function testJsonLdPaste()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
$_GET['jsonld'] = 'paste';
|
$_GET['jsonld'] = 'paste';
|
||||||
|
@ -220,7 +207,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testJsonLdComment()
|
public function testJsonLdComment()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
$_GET['jsonld'] = 'comment';
|
$_GET['jsonld'] = 'comment';
|
||||||
|
@ -240,7 +226,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testJsonLdPasteMeta()
|
public function testJsonLdPasteMeta()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
$_GET['jsonld'] = 'pastemeta';
|
$_GET['jsonld'] = 'pastemeta';
|
||||||
|
@ -260,7 +245,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testJsonLdCommentMeta()
|
public function testJsonLdCommentMeta()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
$_GET['jsonld'] = 'commentmeta';
|
$_GET['jsonld'] = 'commentmeta';
|
||||||
|
@ -280,7 +264,6 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testJsonLdInvalid()
|
public function testJsonLdInvalid()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPasteWithAttachment();
|
$paste = Helper::getPasteWithAttachment();
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
$_GET['jsonld'] = CONF;
|
$_GET['jsonld'] = CONF;
|
||||||
|
|
|
@ -20,13 +20,12 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
/* Setup Routine */
|
/* Setup Routine */
|
||||||
Helper::confRestore();
|
|
||||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||||
if (!is_dir($this->_path)) {
|
if (!is_dir($this->_path)) {
|
||||||
mkdir($this->_path);
|
mkdir($this->_path);
|
||||||
}
|
}
|
||||||
ServerSalt::setPath($this->_path);
|
ServerSalt::setPath($this->_path);
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||||
$options['purge']['limit'] = 0;
|
$options['purge']['limit'] = 0;
|
||||||
$options['model'] = array(
|
$options['model'] = array(
|
||||||
'class' => 'Database',
|
'class' => 'Database',
|
||||||
|
@ -47,6 +46,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
{
|
{
|
||||||
/* Tear Down Routine */
|
/* Tear Down Routine */
|
||||||
|
unlink(CONF);
|
||||||
Helper::confRestore();
|
Helper::confRestore();
|
||||||
Helper::rmDir($this->_path);
|
Helper::rmDir($this->_path);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,6 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
'pwd' => null,
|
'pwd' => null,
|
||||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||||
);
|
);
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$model = new Model(new Configuration);
|
$model = new Model(new Configuration);
|
||||||
|
|
||||||
|
@ -382,7 +381,6 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
'pwd' => null,
|
'pwd' => null,
|
||||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||||
);
|
);
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$model = new Model(new Configuration);
|
$model = new Model(new Configuration);
|
||||||
|
|
||||||
|
@ -420,7 +418,6 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||||
'pwd' => null,
|
'pwd' => null,
|
||||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||||
);
|
);
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$model = new Model(new Configuration);
|
$model = new Model(new Configuration);
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,13 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
/* Setup Routine */
|
/* Setup Routine */
|
||||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||||
ServerSalt::setPath($this->_path);
|
|
||||||
$this->reset();
|
$this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tearDown()
|
public function tearDown()
|
||||||
{
|
{
|
||||||
/* Tear Down Routine */
|
/* Tear Down Routine */
|
||||||
|
unlink(CONF);
|
||||||
Helper::confRestore();
|
Helper::confRestore();
|
||||||
Helper::rmDir($this->_path);
|
Helper::rmDir($this->_path);
|
||||||
}
|
}
|
||||||
|
@ -35,13 +35,13 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
if ($this->_model->exists(Helper::getPasteId())) {
|
if ($this->_model->exists(Helper::getPasteId())) {
|
||||||
$this->_model->delete(Helper::getPasteId());
|
$this->_model->delete(Helper::getPasteId());
|
||||||
}
|
}
|
||||||
Helper::confRestore();
|
$options = parse_ini_file(CONF_SAMPLE, true);
|
||||||
$options = parse_ini_file(CONF, true);
|
|
||||||
$options['purge']['dir'] = $this->_path;
|
$options['purge']['dir'] = $this->_path;
|
||||||
$options['traffic']['dir'] = $this->_path;
|
$options['traffic']['dir'] = $this->_path;
|
||||||
$options['model_options']['dir'] = $this->_path;
|
$options['model_options']['dir'] = $this->_path;
|
||||||
Helper::confBackup();
|
Helper::confBackup();
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
|
ServerSalt::setPath($this->_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +49,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testView()
|
public function testView()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
ob_start();
|
ob_start();
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
$content = ob_get_contents();
|
$content = ob_get_contents();
|
||||||
|
@ -71,10 +70,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testViewLanguageSelection()
|
public function testViewLanguageSelection()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['main']['languageselection'] = true;
|
$options['main']['languageselection'] = true;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_COOKIE['lang'] = 'de';
|
$_COOKIE['lang'] = 'de';
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -93,11 +90,9 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testViewForceLanguageDefault()
|
public function testViewForceLanguageDefault()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['main']['languageselection'] = false;
|
$options['main']['languageselection'] = false;
|
||||||
$options['main']['languagedefault'] = 'fr';
|
$options['main']['languagedefault'] = 'fr';
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_COOKIE['lang'] = 'de';
|
$_COOKIE['lang'] = 'de';
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -117,10 +112,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
public function testViewUrlShortener()
|
public function testViewUrlShortener()
|
||||||
{
|
{
|
||||||
$shortener = 'https://shortener.example.com/api?link=';
|
$shortener = 'https://shortener.example.com/api?link=';
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['main']['urlshortener'] = $shortener;
|
$options['main']['urlshortener'] = $shortener;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_COOKIE['lang'] = 'de';
|
$_COOKIE['lang'] = 'de';
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -139,7 +132,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testHtaccess()
|
public function testHtaccess()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$file = $this->_path . DIRECTORY_SEPARATOR . '.htaccess';
|
$file = $this->_path . DIRECTORY_SEPARATOR . '.htaccess';
|
||||||
@unlink($file);
|
@unlink($file);
|
||||||
|
|
||||||
|
@ -160,8 +152,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testConf()
|
public function testConf()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
Helper::confBackup();
|
|
||||||
file_put_contents(CONF, '');
|
file_put_contents(CONF, '');
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
}
|
}
|
||||||
|
@ -171,10 +161,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreate()
|
public function testCreate()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
|
@ -200,10 +188,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidTimelimit()
|
public function testCreateInvalidTimelimit()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste(array('expire' => 25));
|
$_POST = Helper::getPaste(array('expire' => 25));
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
|
@ -230,11 +216,9 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidSize()
|
public function testCreateInvalidSize()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['main']['sizelimit'] = 10;
|
$options['main']['sizelimit'] = 10;
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
|
@ -254,10 +238,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateProxyHeader()
|
public function testCreateProxyHeader()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['header'] = 'X_FORWARDED_FOR';
|
$options['traffic']['header'] = 'X_FORWARDED_FOR';
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_SERVER['HTTP_X_FORWARDED_FOR'] = '::2';
|
$_SERVER['HTTP_X_FORWARDED_FOR'] = '::2';
|
||||||
|
@ -284,10 +266,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateDuplicateId()
|
public function testCreateDuplicateId()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
|
@ -308,10 +288,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateValidExpire()
|
public function testCreateValidExpire()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_POST['expire'] = '5min';
|
$_POST['expire'] = '5min';
|
||||||
|
@ -341,10 +319,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateValidExpireWithDiscussion()
|
public function testCreateValidExpireWithDiscussion()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_POST['expire'] = '5min';
|
$_POST['expire'] = '5min';
|
||||||
|
@ -375,10 +351,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidExpire()
|
public function testCreateInvalidExpire()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_POST['expire'] = 'foo';
|
$_POST['expire'] = 'foo';
|
||||||
|
@ -405,10 +379,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidBurn()
|
public function testCreateInvalidBurn()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_POST['burnafterreading'] = 'neither 1 nor 0';
|
$_POST['burnafterreading'] = 'neither 1 nor 0';
|
||||||
|
@ -429,10 +401,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidOpenDiscussion()
|
public function testCreateInvalidOpenDiscussion()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_POST['opendiscussion'] = 'neither 1 nor 0';
|
$_POST['opendiscussion'] = 'neither 1 nor 0';
|
||||||
|
@ -453,11 +423,9 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateAttachment()
|
public function testCreateAttachment()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
$options['main']['fileupload'] = true;
|
$options['main']['fileupload'] = true;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPasteWithAttachment();
|
$_POST = Helper::getPasteWithAttachment();
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
|
@ -491,11 +459,9 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateBrokenAttachmentUpload()
|
public function testCreateBrokenAttachmentUpload()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
$options['main']['fileupload'] = true;
|
$options['main']['fileupload'] = true;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPasteWithAttachment();
|
$_POST = Helper::getPasteWithAttachment();
|
||||||
unset($_POST['attachment']);
|
unset($_POST['attachment']);
|
||||||
|
@ -517,7 +483,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateTooSoon()
|
public function testCreateTooSoon()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||||
|
@ -540,10 +505,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateValidNick()
|
public function testCreateValidNick()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getPaste();
|
$_POST = Helper::getPaste();
|
||||||
$_POST['nickname'] = Helper::getComment()['meta']['nickname'];
|
$_POST['nickname'] = Helper::getComment()['meta']['nickname'];
|
||||||
|
@ -570,10 +533,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidNick()
|
public function testCreateInvalidNick()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getCommentPost();
|
$_POST = Helper::getCommentPost();
|
||||||
$_POST['pasteid'] = Helper::getPasteId();
|
$_POST['pasteid'] = Helper::getPasteId();
|
||||||
|
@ -597,10 +558,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateComment()
|
public function testCreateComment()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getCommentPost();
|
$_POST = Helper::getCommentPost();
|
||||||
$_POST['pasteid'] = Helper::getPasteId();
|
$_POST['pasteid'] = Helper::getPasteId();
|
||||||
|
@ -623,10 +582,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateInvalidComment()
|
public function testCreateInvalidComment()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getCommentPost();
|
$_POST = Helper::getCommentPost();
|
||||||
$_POST['pasteid'] = Helper::getPasteId();
|
$_POST['pasteid'] = Helper::getPasteId();
|
||||||
|
@ -649,10 +606,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateCommentDiscussionDisabled()
|
public function testCreateCommentDiscussionDisabled()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getCommentPost();
|
$_POST = Helper::getCommentPost();
|
||||||
$_POST['pasteid'] = Helper::getPasteId();
|
$_POST['pasteid'] = Helper::getPasteId();
|
||||||
|
@ -676,10 +631,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateCommentInvalidPaste()
|
public function testCreateCommentInvalidPaste()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$_POST = Helper::getCommentPost();
|
$_POST = Helper::getCommentPost();
|
||||||
$_POST['pasteid'] = Helper::getPasteId();
|
$_POST['pasteid'] = Helper::getPasteId();
|
||||||
|
@ -701,10 +654,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testCreateDuplicateComment()
|
public function testCreateDuplicateComment()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$options = parse_ini_file(CONF, true);
|
$options = parse_ini_file(CONF, true);
|
||||||
$options['traffic']['limit'] = 0;
|
$options['traffic']['limit'] = 0;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment());
|
$this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment());
|
||||||
|
@ -729,7 +680,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testRead()
|
public function testRead()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -750,7 +700,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadInvalidId()
|
public function testReadInvalidId()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$_SERVER['QUERY_STRING'] = 'foo';
|
$_SERVER['QUERY_STRING'] = 'foo';
|
||||||
ob_start();
|
ob_start();
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
|
@ -768,7 +717,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadNonexisting()
|
public function testReadNonexisting()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||||
ob_start();
|
ob_start();
|
||||||
new PrivateBin;
|
new PrivateBin;
|
||||||
|
@ -786,7 +734,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadExpired()
|
public function testReadExpired()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$expiredPaste = Helper::getPaste(array('expire_date' => 1344803344));
|
$expiredPaste = Helper::getPaste(array('expire_date' => 1344803344));
|
||||||
$this->_model->create(Helper::getPasteId(), $expiredPaste);
|
$this->_model->create(Helper::getPasteId(), $expiredPaste);
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||||
|
@ -806,7 +753,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadBurn()
|
public function testReadBurn()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$burnPaste = Helper::getPaste(array('burnafterreading' => true));
|
$burnPaste = Helper::getPaste(array('burnafterreading' => true));
|
||||||
$this->_model->create(Helper::getPasteId(), $burnPaste);
|
$this->_model->create(Helper::getPasteId(), $burnPaste);
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||||
|
@ -860,7 +806,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadJson()
|
public function testReadJson()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPaste();
|
$paste = Helper::getPaste();
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||||
|
@ -886,7 +831,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadInvalidJson()
|
public function testReadInvalidJson()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -902,7 +846,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadOldSyntax()
|
public function testReadOldSyntax()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$oldPaste = Helper::getPaste();
|
$oldPaste = Helper::getPaste();
|
||||||
$meta = array(
|
$meta = array(
|
||||||
'syntaxcoloring' => true,
|
'syntaxcoloring' => true,
|
||||||
|
@ -931,7 +874,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testReadOldFormat()
|
public function testReadOldFormat()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$oldPaste = Helper::getPaste();
|
$oldPaste = Helper::getPaste();
|
||||||
unset($oldPaste['meta']['formatter']);
|
unset($oldPaste['meta']['formatter']);
|
||||||
$this->_model->create(Helper::getPasteId(), $oldPaste);
|
$this->_model->create(Helper::getPasteId(), $oldPaste);
|
||||||
|
@ -956,7 +898,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDelete()
|
public function testDelete()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||||
$paste = $this->_model->read(Helper::getPasteId());
|
$paste = $this->_model->read(Helper::getPasteId());
|
||||||
|
@ -979,7 +920,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteInvalidId()
|
public function testDeleteInvalidId()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$_GET['pasteid'] = 'foo';
|
$_GET['pasteid'] = 'foo';
|
||||||
$_GET['deletetoken'] = 'bar';
|
$_GET['deletetoken'] = 'bar';
|
||||||
|
@ -1000,7 +940,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteInexistantId()
|
public function testDeleteInexistantId()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$_GET['pasteid'] = Helper::getPasteId();
|
$_GET['pasteid'] = Helper::getPasteId();
|
||||||
$_GET['deletetoken'] = 'bar';
|
$_GET['deletetoken'] = 'bar';
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -1019,7 +958,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteInvalidToken()
|
public function testDeleteInvalidToken()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$_GET['pasteid'] = Helper::getPasteId();
|
$_GET['pasteid'] = Helper::getPasteId();
|
||||||
$_GET['deletetoken'] = 'bar';
|
$_GET['deletetoken'] = 'bar';
|
||||||
|
@ -1040,7 +978,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteBurnAfterReading()
|
public function testDeleteBurnAfterReading()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$burnPaste = Helper::getPaste(array('burnafterreading' => true));
|
$burnPaste = Helper::getPaste(array('burnafterreading' => true));
|
||||||
$this->_model->create(Helper::getPasteId(), $burnPaste);
|
$this->_model->create(Helper::getPasteId(), $burnPaste);
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||||
|
@ -1062,7 +999,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteInvalidBurnAfterReading()
|
public function testDeleteInvalidBurnAfterReading()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||||
$_POST['deletetoken'] = 'burnafterreading';
|
$_POST['deletetoken'] = 'burnafterreading';
|
||||||
|
@ -1083,7 +1019,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteExpired()
|
public function testDeleteExpired()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$expiredPaste = Helper::getPaste(array('expire_date' => 1000));
|
$expiredPaste = Helper::getPaste(array('expire_date' => 1000));
|
||||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not exist before being created');
|
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not exist before being created');
|
||||||
$this->_model->create(Helper::getPasteId(), $expiredPaste);
|
$this->_model->create(Helper::getPasteId(), $expiredPaste);
|
||||||
|
@ -1107,7 +1042,6 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
public function testDeleteMissingPerPasteSalt()
|
public function testDeleteMissingPerPasteSalt()
|
||||||
{
|
{
|
||||||
$this->reset();
|
|
||||||
$paste = Helper::getPaste();
|
$paste = Helper::getPaste();
|
||||||
unset($paste['meta']['salt']);
|
unset($paste['meta']['salt']);
|
||||||
$this->_model->create(Helper::getPasteId(), $paste);
|
$this->_model->create(Helper::getPasteId(), $paste);
|
||||||
|
|
|
@ -23,7 +23,6 @@ class PrivateBinWithDbTest extends PrivateBinTest
|
||||||
if (!is_dir($this->_path)) {
|
if (!is_dir($this->_path)) {
|
||||||
mkdir($this->_path);
|
mkdir($this->_path);
|
||||||
}
|
}
|
||||||
ServerSalt::setPath($this->_path);
|
|
||||||
$this->_options['dsn'] = 'sqlite:' . $this->_path . DIRECTORY_SEPARATOR . 'tst.sq3';
|
$this->_options['dsn'] = 'sqlite:' . $this->_path . DIRECTORY_SEPARATOR . 'tst.sq3';
|
||||||
$this->_model = Database::getInstance($this->_options);
|
$this->_model = Database::getInstance($this->_options);
|
||||||
$this->reset();
|
$this->reset();
|
||||||
|
@ -37,10 +36,7 @@ class PrivateBinWithDbTest extends PrivateBinTest
|
||||||
$options['model'] = array(
|
$options['model'] = array(
|
||||||
'class' => 'Database',
|
'class' => 'Database',
|
||||||
);
|
);
|
||||||
$options['purge']['dir'] = $this->_path;
|
|
||||||
$options['traffic']['dir'] = $this->_path;
|
|
||||||
$options['model_options'] = $this->_options;
|
$options['model_options'] = $this->_options;
|
||||||
Helper::confBackup();
|
|
||||||
Helper::createIniFile(CONF, $options);
|
Helper::createIniFile(CONF, $options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue