mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2025-04-20 07:35:46 -04:00
Merge c6d4bba440068c106bb389586f763b8be4b01f41 into bd30ae419a10dee4f6d1d27d57e4d07be2e5a97c
This commit is contained in:
commit
9a9208095e
@ -1,12 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@ -14,5 +16,5 @@
|
||||
define('PATH', '');
|
||||
|
||||
define('PUBLIC_PATH', __DIR__);
|
||||
require PATH . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
new PrivateBin\PrivateBin;
|
||||
require PATH.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';
|
||||
new PrivateBin\PrivateBin();
|
||||
|
@ -1,108 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
use PrivateBin\I18n;
|
||||
use Exception;
|
||||
use PDO;
|
||||
|
||||
/**
|
||||
* Configuration
|
||||
* Configuration.
|
||||
*
|
||||
* parses configuration file, ensures default values present
|
||||
*/
|
||||
class Configuration
|
||||
{
|
||||
/**
|
||||
* parsed configuration
|
||||
* parsed configuration.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_configuration;
|
||||
|
||||
/**
|
||||
* default configuration
|
||||
* default configuration.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_defaults = array(
|
||||
'main' => array(
|
||||
'discussion' => true,
|
||||
'opendiscussion' => false,
|
||||
'password' => true,
|
||||
'fileupload' => false,
|
||||
private static $_defaults = [
|
||||
'main' => [
|
||||
'discussion' => true,
|
||||
'opendiscussion' => false,
|
||||
'password' => true,
|
||||
'fileupload' => false,
|
||||
'burnafterreadingselected' => false,
|
||||
'defaultformatter' => 'plaintext',
|
||||
'syntaxhighlightingtheme' => null,
|
||||
'sizelimit' => 2097152,
|
||||
'template' => 'bootstrap',
|
||||
'notice' => '',
|
||||
'languageselection' => false,
|
||||
'languagedefault' => '',
|
||||
'urlshortener' => '',
|
||||
'icon' => 'identicon',
|
||||
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; referrer no-referrer;',
|
||||
'zerobincompatibility' => false,
|
||||
),
|
||||
'expire' => array(
|
||||
'defaultformatter' => 'plaintext',
|
||||
'syntaxhighlightingtheme' => null,
|
||||
'sizelimit' => 2097152,
|
||||
'template' => 'bootstrap',
|
||||
'notice' => '',
|
||||
'languageselection' => false,
|
||||
'languagedefault' => '',
|
||||
'urlshortener' => '',
|
||||
'icon' => 'identicon',
|
||||
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; referrer no-referrer;',
|
||||
'zerobincompatibility' => false,
|
||||
],
|
||||
'expire' => [
|
||||
'default' => '1week',
|
||||
'clone' => true,
|
||||
),
|
||||
'expire_options' => array(
|
||||
'5min' => 300,
|
||||
'10min' => 600,
|
||||
'1hour' => 3600,
|
||||
'1day' => 86400,
|
||||
'1week' => 604800,
|
||||
'clone' => true,
|
||||
],
|
||||
'expire_options' => [
|
||||
'5min' => 300,
|
||||
'10min' => 600,
|
||||
'1hour' => 3600,
|
||||
'1day' => 86400,
|
||||
'1week' => 604800,
|
||||
'1month' => 2592000,
|
||||
'1year' => 31536000,
|
||||
'never' => 0,
|
||||
),
|
||||
'formatter_options' => array(
|
||||
'plaintext' => 'Plain Text',
|
||||
'1year' => 31536000,
|
||||
'never' => 0,
|
||||
],
|
||||
'formatter_options' => [
|
||||
'plaintext' => 'Plain Text',
|
||||
'syntaxhighlighting' => 'Source Code',
|
||||
'markdown' => 'Markdown',
|
||||
),
|
||||
'traffic' => array(
|
||||
'limit' => 10,
|
||||
'markdown' => 'Markdown',
|
||||
],
|
||||
'traffic' => [
|
||||
'limit' => 10,
|
||||
'header' => null,
|
||||
'dir' => 'data',
|
||||
),
|
||||
'purge' => array(
|
||||
'limit' => 300,
|
||||
'dir' => 'data',
|
||||
],
|
||||
'purge' => [
|
||||
'limit' => 300,
|
||||
'batchsize' => 10,
|
||||
'dir' => 'data',
|
||||
),
|
||||
'model' => array(
|
||||
'dir' => 'data',
|
||||
],
|
||||
'model' => [
|
||||
'class' => 'Filesystem',
|
||||
),
|
||||
'model_options' => array(
|
||||
],
|
||||
'model_options' => [
|
||||
'dir' => 'data',
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* parse configuration file and ensure default configuration values are present
|
||||
* parse configuration file and ensure default configuration values are present.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$config = array();
|
||||
$configFile = PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini';
|
||||
$config = [];
|
||||
$configFile = PATH.'cfg'.DIRECTORY_SEPARATOR.'conf.ini';
|
||||
if (is_readable($configFile)) {
|
||||
$config = parse_ini_file($configFile, true);
|
||||
foreach (array('main', 'model', 'model_options') as $section) {
|
||||
foreach (['main', 'model', 'model_options'] as $section) {
|
||||
if (!array_key_exists($section, $config)) {
|
||||
throw new Exception(I18n::_('PrivateBin requires configuration section [%s] to be present in configuration file.', $section), 2);
|
||||
}
|
||||
@ -114,7 +114,7 @@ class Configuration
|
||||
if (!array_key_exists($section, $config) || count($config[$section]) == 0) {
|
||||
$this->_configuration[$section] = $values;
|
||||
if (array_key_exists('dir', $this->_configuration[$section])) {
|
||||
$this->_configuration[$section]['dir'] = PATH . $this->_configuration[$section]['dir'];
|
||||
$this->_configuration[$section]['dir'] = PATH.$this->_configuration[$section]['dir'];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -122,16 +122,16 @@ class Configuration
|
||||
elseif (
|
||||
$section == 'model_options' && in_array(
|
||||
$this->_configuration['model']['class'],
|
||||
array('Database', 'privatebin_db', 'zerobin_db')
|
||||
['Database', 'privatebin_db', 'zerobin_db']
|
||||
)
|
||||
) {
|
||||
$values = array(
|
||||
'dsn' => 'sqlite:' . PATH . 'data' . DIRECTORY_SEPARATOR . 'db.sq3',
|
||||
$values = [
|
||||
'dsn' => 'sqlite:'.PATH.'data'.DIRECTORY_SEPARATOR.'db.sq3',
|
||||
'tbl' => null,
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_PERSISTENT => true),
|
||||
);
|
||||
'opt' => [PDO::ATTR_PERSISTENT => true],
|
||||
];
|
||||
}
|
||||
|
||||
// "*_options" sections don't require all defaults to be set
|
||||
@ -149,7 +149,7 @@ class Configuration
|
||||
else {
|
||||
foreach ($values as $key => $val) {
|
||||
if ($key == 'dir') {
|
||||
$val = PATH . $val;
|
||||
$val = PATH.$val;
|
||||
}
|
||||
$result = $val;
|
||||
if (array_key_exists($key, $config[$section])) {
|
||||
@ -157,9 +157,9 @@ class Configuration
|
||||
$result = $config[$section][$key];
|
||||
} elseif (is_bool($val)) {
|
||||
$val = strtolower($config[$section][$key]);
|
||||
if (in_array($val, array('true', 'yes', 'on'))) {
|
||||
if (in_array($val, ['true', 'yes', 'on'])) {
|
||||
$result = true;
|
||||
} elseif (in_array($val, array('false', 'no', 'off'))) {
|
||||
} elseif (in_array($val, ['false', 'no', 'off'])) {
|
||||
$result = false;
|
||||
} else {
|
||||
$result = (bool) $config[$section][$key];
|
||||
@ -182,8 +182,8 @@ class Configuration
|
||||
);
|
||||
|
||||
$this->_configuration['model']['class'] = str_replace(
|
||||
array('privatebin_data', 'privatebin_db'),
|
||||
array('Filesystem', 'Database'),
|
||||
['privatebin_data', 'privatebin_db'],
|
||||
['Filesystem', 'Database'],
|
||||
$this->_configuration['model']['class']
|
||||
);
|
||||
|
||||
@ -194,7 +194,7 @@ class Configuration
|
||||
}
|
||||
|
||||
/**
|
||||
* get configuration as array
|
||||
* get configuration as array.
|
||||
*
|
||||
* return array
|
||||
*/
|
||||
@ -204,7 +204,7 @@ class Configuration
|
||||
}
|
||||
|
||||
/**
|
||||
* get default configuration as array
|
||||
* get default configuration as array.
|
||||
*
|
||||
* return array
|
||||
*/
|
||||
@ -214,34 +214,38 @@ class Configuration
|
||||
}
|
||||
|
||||
/**
|
||||
* get a key from the configuration, typically the main section or all keys
|
||||
* get a key from the configuration, typically the main section or all keys.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $section defaults to main
|
||||
*
|
||||
* @throws Exception
|
||||
* return mixed
|
||||
* return mixed
|
||||
*/
|
||||
public function getKey($key, $section = 'main')
|
||||
{
|
||||
$options = $this->getSection($section);
|
||||
if (!array_key_exists($key, $options)) {
|
||||
throw new Exception(I18n::_('Invalid data.') . " $section / $key", 4);
|
||||
throw new Exception(I18n::_('Invalid data.')." $section / $key", 4);
|
||||
}
|
||||
|
||||
return $this->_configuration[$section][$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* get a section from the configuration, must exist
|
||||
* get a section from the configuration, must exist.
|
||||
*
|
||||
* @param string $section
|
||||
*
|
||||
* @throws Exception
|
||||
* return mixed
|
||||
* return mixed
|
||||
*/
|
||||
public function getSection($section)
|
||||
{
|
||||
if (!array_key_exists($section, $this->_configuration)) {
|
||||
throw new Exception(I18n::_('PrivateBin requires configuration section [%s] to be present in configuration file.', $section), 3);
|
||||
}
|
||||
|
||||
return $this->_configuration[$section];
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Data;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* AbstractData
|
||||
* AbstractData.
|
||||
*
|
||||
* Abstract model for PrivateBin data access, implemented as a singleton.
|
||||
*/
|
||||
abstract class AbstractData
|
||||
{
|
||||
/**
|
||||
* singleton instance
|
||||
* singleton instance.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var AbstractData
|
||||
*/
|
||||
protected static $_instance = null;
|
||||
|
||||
/**
|
||||
* enforce singleton, disable constructor
|
||||
* enforce singleton, disable constructor.
|
||||
*
|
||||
* Instantiate using {@link getInstance()}, privatebin is a singleton object.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* enforce singleton, disable cloning
|
||||
* enforce singleton, disable cloning.
|
||||
*
|
||||
* Instantiate using {@link getInstance()}, privatebin is a singleton object.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* get instance of singleton
|
||||
* get instance of singleton.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param array $options
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return privatebin_abstract
|
||||
*/
|
||||
public static function getInstance($options)
|
||||
@ -67,9 +65,9 @@ abstract class AbstractData
|
||||
/**
|
||||
* Create a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param array $paste
|
||||
* @param string $pasteid
|
||||
* @param array $paste
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function create($pasteid, $paste);
|
||||
@ -77,8 +75,8 @@ abstract class AbstractData
|
||||
/**
|
||||
* Read a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return stdClass|false
|
||||
*/
|
||||
abstract public function read($pasteid);
|
||||
@ -86,8 +84,8 @@ abstract class AbstractData
|
||||
/**
|
||||
* Delete a paste and its discussion.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function delete($pasteid);
|
||||
@ -95,8 +93,8 @@ abstract class AbstractData
|
||||
/**
|
||||
* Test if a paste exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function exists($pasteid);
|
||||
@ -104,11 +102,11 @@ abstract class AbstractData
|
||||
/**
|
||||
* Create a comment in a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param array $comment
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param array $comment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function createComment($pasteid, $parentid, $commentid, $comment);
|
||||
@ -116,8 +114,8 @@ abstract class AbstractData
|
||||
/**
|
||||
* Read all comments of paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function readComments($pasteid);
|
||||
@ -125,19 +123,19 @@ abstract class AbstractData
|
||||
/**
|
||||
* Test if a comment exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function existsComment($pasteid, $parentid, $commentid);
|
||||
|
||||
/**
|
||||
* Returns up to batch size number of paste ids that have expired
|
||||
* Returns up to batch size number of paste ids that have expired.
|
||||
*
|
||||
* @param int $batchsize
|
||||
*
|
||||
* @access protected
|
||||
* @param int $batchsize
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function _getExpiredPastes($batchsize);
|
||||
@ -145,8 +143,8 @@ abstract class AbstractData
|
||||
/**
|
||||
* Perform a purge of old pastes, at most the given batchsize is deleted.
|
||||
*
|
||||
* @access public
|
||||
* @param int $batchsize
|
||||
* @param int $batchsize
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function purge($batchsize)
|
||||
@ -165,9 +163,9 @@ abstract class AbstractData
|
||||
/**
|
||||
* Get next free slot for comment from postdate.
|
||||
*
|
||||
* @access public
|
||||
* @param array $comments
|
||||
* @param int|string $postdate
|
||||
* @param array $comments
|
||||
* @param int|string $postdate
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
protected function getOpenSlot(&$comments, $postdate)
|
||||
@ -178,8 +176,10 @@ abstract class AbstractData
|
||||
$parts[1] = 0;
|
||||
}
|
||||
++$parts[1];
|
||||
|
||||
return $this->getOpenSlot($comments, implode('.', $parts));
|
||||
}
|
||||
|
||||
return $postdate;
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Data;
|
||||
|
||||
use PrivateBin\PrivateBin;
|
||||
use Exception;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use PrivateBin\PrivateBin;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Database
|
||||
* Database.
|
||||
*
|
||||
* Model for database access, implemented as a singleton.
|
||||
*/
|
||||
class Database extends AbstractData
|
||||
{
|
||||
/**
|
||||
* cache for select queries
|
||||
* cache for select queries.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_cache = array();
|
||||
private static $_cache = [];
|
||||
|
||||
/**
|
||||
* instance of database connection
|
||||
* instance of database connection.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var PDO
|
||||
*/
|
||||
private static $_db;
|
||||
|
||||
/**
|
||||
* table prefix
|
||||
* table prefix.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_prefix = '';
|
||||
|
||||
/**
|
||||
* database type
|
||||
* database type.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_type = '';
|
||||
|
||||
/**
|
||||
* get instance of singleton
|
||||
* get instance of singleton.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param array $options
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return Database
|
||||
*/
|
||||
public static function getInstance($options = null)
|
||||
{
|
||||
// if needed initialize the singleton
|
||||
if (!(self::$_instance instanceof self)) {
|
||||
self::$_instance = new self;
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
if (is_array($options)) {
|
||||
@ -89,17 +92,17 @@ class Database extends AbstractData
|
||||
array_key_exists('opt', $options)
|
||||
) {
|
||||
// set default options
|
||||
$options['opt'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
||||
$options['opt'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
||||
$options['opt'][PDO::ATTR_EMULATE_PREPARES] = false;
|
||||
$options['opt'][PDO::ATTR_PERSISTENT] = true;
|
||||
$db_tables_exist = true;
|
||||
$options['opt'][PDO::ATTR_PERSISTENT] = true;
|
||||
$db_tables_exist = true;
|
||||
|
||||
// setup type and dabase connection
|
||||
self::$_type = strtolower(
|
||||
substr($options['dsn'], 0, strpos($options['dsn'], ':'))
|
||||
);
|
||||
$tableQuery = self::_getTableQuery(self::$_type);
|
||||
self::$_db = new PDO(
|
||||
self::$_db = new PDO(
|
||||
$options['dsn'],
|
||||
$options['usr'],
|
||||
$options['pwd'],
|
||||
@ -150,9 +153,9 @@ class Database extends AbstractData
|
||||
/**
|
||||
* Create a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param array $paste
|
||||
* @param string $pasteid
|
||||
* @param array $paste
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function create($pasteid, $paste)
|
||||
@ -168,8 +171,8 @@ class Database extends AbstractData
|
||||
}
|
||||
|
||||
$opendiscussion = $burnafterreading = false;
|
||||
$attachment = $attachmentname = '';
|
||||
$meta = $paste['meta'];
|
||||
$attachment = $attachmentname = '';
|
||||
$meta = $paste['meta'];
|
||||
unset($meta['postdate']);
|
||||
$expire_date = 0;
|
||||
if (array_key_exists('expire_date', $paste['meta'])) {
|
||||
@ -192,10 +195,11 @@ class Database extends AbstractData
|
||||
$attachmentname = $paste['meta']['attachmentname'];
|
||||
unset($meta['attachmentname']);
|
||||
}
|
||||
|
||||
return self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('paste') .
|
||||
'INSERT INTO '.self::_sanitizeIdentifier('paste').
|
||||
' VALUES(?,?,?,?,?,?,?,?,?)',
|
||||
array(
|
||||
[
|
||||
$pasteid,
|
||||
$paste['data'],
|
||||
$paste['meta']['postdate'],
|
||||
@ -205,15 +209,15 @@ class Database extends AbstractData
|
||||
json_encode($meta),
|
||||
$attachment,
|
||||
$attachmentname,
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return stdClass|false
|
||||
*/
|
||||
public function read($pasteid)
|
||||
@ -222,19 +226,19 @@ class Database extends AbstractData
|
||||
!array_key_exists($pasteid, self::$_cache)
|
||||
) {
|
||||
self::$_cache[$pasteid] = false;
|
||||
$paste = self::_select(
|
||||
'SELECT * FROM ' . self::_sanitizeIdentifier('paste') .
|
||||
' WHERE dataid = ?', array($pasteid), true
|
||||
$paste = self::_select(
|
||||
'SELECT * FROM '.self::_sanitizeIdentifier('paste').
|
||||
' WHERE dataid = ?', [$pasteid], true
|
||||
);
|
||||
|
||||
if (false !== $paste) {
|
||||
// create object
|
||||
self::$_cache[$pasteid] = new stdClass;
|
||||
self::$_cache[$pasteid] = new stdClass();
|
||||
self::$_cache[$pasteid]->data = $paste['data'];
|
||||
|
||||
$meta = json_decode($paste['meta']);
|
||||
if (!is_object($meta)) {
|
||||
$meta = new stdClass;
|
||||
$meta = new stdClass();
|
||||
}
|
||||
|
||||
// support older attachments
|
||||
@ -253,9 +257,9 @@ class Database extends AbstractData
|
||||
self::$_cache[$pasteid]->attachmentname = $paste['attachmentname'];
|
||||
}
|
||||
}
|
||||
self::$_cache[$pasteid]->meta = $meta;
|
||||
self::$_cache[$pasteid]->meta = $meta;
|
||||
self::$_cache[$pasteid]->meta->postdate = (int) $paste['postdate'];
|
||||
$expire_date = (int) $paste['expiredate'];
|
||||
$expire_date = (int) $paste['expiredate'];
|
||||
if (
|
||||
$expire_date > 0
|
||||
) {
|
||||
@ -280,19 +284,19 @@ class Database extends AbstractData
|
||||
/**
|
||||
* Delete a paste and its discussion.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete($pasteid)
|
||||
{
|
||||
self::_exec(
|
||||
'DELETE FROM ' . self::_sanitizeIdentifier('paste') .
|
||||
' WHERE dataid = ?', array($pasteid)
|
||||
'DELETE FROM '.self::_sanitizeIdentifier('paste').
|
||||
' WHERE dataid = ?', [$pasteid]
|
||||
);
|
||||
self::_exec(
|
||||
'DELETE FROM ' . self::_sanitizeIdentifier('comment') .
|
||||
' WHERE pasteid = ?', array($pasteid)
|
||||
'DELETE FROM '.self::_sanitizeIdentifier('comment').
|
||||
' WHERE pasteid = ?', [$pasteid]
|
||||
);
|
||||
if (
|
||||
array_key_exists($pasteid, self::$_cache)
|
||||
@ -304,8 +308,8 @@ class Database extends AbstractData
|
||||
/**
|
||||
* Test if a paste exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($pasteid)
|
||||
@ -315,30 +319,32 @@ class Database extends AbstractData
|
||||
) {
|
||||
self::$_cache[$pasteid] = $this->read($pasteid);
|
||||
}
|
||||
|
||||
return (bool) self::$_cache[$pasteid];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a comment in a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param array $comment
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param array $comment
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function createComment($pasteid, $parentid, $commentid, $comment)
|
||||
{
|
||||
foreach (array('nickname', 'vizhash') as $key) {
|
||||
foreach (['nickname', 'vizhash'] as $key) {
|
||||
if (!array_key_exists($key, $comment['meta'])) {
|
||||
$comment['meta'][$key] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('comment') .
|
||||
'INSERT INTO '.self::_sanitizeIdentifier('comment').
|
||||
' VALUES(?,?,?,?,?,?,?)',
|
||||
array(
|
||||
[
|
||||
$commentid,
|
||||
$pasteid,
|
||||
$parentid,
|
||||
@ -346,34 +352,34 @@ class Database extends AbstractData
|
||||
$comment['meta']['nickname'],
|
||||
$comment['meta']['vizhash'],
|
||||
$comment['meta']['postdate'],
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all comments of paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function readComments($pasteid)
|
||||
{
|
||||
$rows = self::_select(
|
||||
'SELECT * FROM ' . self::_sanitizeIdentifier('comment') .
|
||||
' WHERE pasteid = ?', array($pasteid)
|
||||
'SELECT * FROM '.self::_sanitizeIdentifier('comment').
|
||||
' WHERE pasteid = ?', [$pasteid]
|
||||
);
|
||||
|
||||
// create comment list
|
||||
$comments = array();
|
||||
$comments = [];
|
||||
if (count($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$i = $this->getOpenSlot($comments, (int) $row['postdate']);
|
||||
$comments[$i] = new stdClass;
|
||||
$comments[$i]->id = $row['dataid'];
|
||||
$comments[$i]->parentid = $row['parentid'];
|
||||
$comments[$i]->data = $row['data'];
|
||||
$comments[$i]->meta = new stdClass;
|
||||
$i = $this->getOpenSlot($comments, (int) $row['postdate']);
|
||||
$comments[$i] = new stdClass();
|
||||
$comments[$i]->id = $row['dataid'];
|
||||
$comments[$i]->parentid = $row['parentid'];
|
||||
$comments[$i]->data = $row['data'];
|
||||
$comments[$i]->meta = new stdClass();
|
||||
$comments[$i]->meta->postdate = (int) $row['postdate'];
|
||||
if (array_key_exists('nickname', $row) && !empty($row['nickname'])) {
|
||||
$comments[$i]->meta->nickname = $row['nickname'];
|
||||
@ -384,76 +390,83 @@ class Database extends AbstractData
|
||||
}
|
||||
ksort($comments);
|
||||
}
|
||||
|
||||
return $comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a comment exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function existsComment($pasteid, $parentid, $commentid)
|
||||
{
|
||||
return (bool) self::_select(
|
||||
'SELECT dataid FROM ' . self::_sanitizeIdentifier('comment') .
|
||||
'SELECT dataid FROM '.self::_sanitizeIdentifier('comment').
|
||||
' WHERE pasteid = ? AND parentid = ? AND dataid = ?',
|
||||
array($pasteid, $parentid, $commentid), true
|
||||
[$pasteid, $parentid, $commentid], true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns up to batch size number of paste ids that have expired
|
||||
* Returns up to batch size number of paste ids that have expired.
|
||||
*
|
||||
* @param int $batchsize
|
||||
*
|
||||
* @access private
|
||||
* @param int $batchsize
|
||||
* @return array
|
||||
*/
|
||||
protected function _getExpiredPastes($batchsize)
|
||||
{
|
||||
$pastes = array();
|
||||
$rows = self::_select(
|
||||
'SELECT dataid FROM ' . self::_sanitizeIdentifier('paste') .
|
||||
' WHERE expiredate < ? LIMIT ?', array(time(), $batchsize)
|
||||
$pastes = [];
|
||||
$rows = self::_select(
|
||||
'SELECT dataid FROM '.self::_sanitizeIdentifier('paste').
|
||||
' WHERE expiredate < ? LIMIT ?', [time(), $batchsize]
|
||||
);
|
||||
if (count($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$pastes[] = $row['dataid'];
|
||||
}
|
||||
}
|
||||
|
||||
return $pastes;
|
||||
}
|
||||
|
||||
/**
|
||||
* execute a statement
|
||||
* execute a statement.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $sql
|
||||
* @param array $params
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $params
|
||||
*
|
||||
* @throws PDOException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function _exec($sql, array $params)
|
||||
{
|
||||
$statement = self::$_db->prepare($sql);
|
||||
$result = $statement->execute($params);
|
||||
$result = $statement->execute($params);
|
||||
$statement->closeCursor();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* run a select statement
|
||||
* run a select statement.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $sql
|
||||
* @param array $params
|
||||
* @param bool $firstOnly if only the first row should be returned
|
||||
*
|
||||
* @param string $sql
|
||||
* @param array $params
|
||||
* @param bool $firstOnly if only the first row should be returned
|
||||
*
|
||||
* @throws PDOException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function _select($sql, array $params, $firstOnly = false)
|
||||
@ -464,16 +477,19 @@ class Database extends AbstractData
|
||||
$statement->fetch(PDO::FETCH_ASSOC) :
|
||||
$statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
$statement->closeCursor();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get table list query, depending on the database type
|
||||
* get table list query, depending on the database type.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $type
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _getTableQuery($type)
|
||||
@ -487,7 +503,7 @@ class Database extends AbstractData
|
||||
break;
|
||||
case 'mssql':
|
||||
$sql = 'SELECT name FROM sysobjects '
|
||||
. "WHERE type = 'U' ORDER BY name";
|
||||
."WHERE type = 'U' ORDER BY name";
|
||||
break;
|
||||
case 'mysql':
|
||||
$sql = 'SHOW TABLES';
|
||||
@ -497,55 +513,60 @@ class Database extends AbstractData
|
||||
break;
|
||||
case 'pgsql':
|
||||
$sql = 'SELECT c.relname AS table_name '
|
||||
. 'FROM pg_class c, pg_user u '
|
||||
. "WHERE c.relowner = u.usesysid AND c.relkind = 'r' "
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) '
|
||||
. "AND c.relname !~ '^(pg_|sql_)' "
|
||||
. 'UNION '
|
||||
. 'SELECT c.relname AS table_name '
|
||||
. 'FROM pg_class c '
|
||||
. "WHERE c.relkind = 'r' "
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) '
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) '
|
||||
. "AND c.relname !~ '^pg_'";
|
||||
.'FROM pg_class c, pg_user u '
|
||||
."WHERE c.relowner = u.usesysid AND c.relkind = 'r' "
|
||||
.'AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) '
|
||||
."AND c.relname !~ '^(pg_|sql_)' "
|
||||
.'UNION '
|
||||
.'SELECT c.relname AS table_name '
|
||||
.'FROM pg_class c '
|
||||
."WHERE c.relkind = 'r' "
|
||||
.'AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) '
|
||||
.'AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) '
|
||||
."AND c.relname !~ '^pg_'";
|
||||
break;
|
||||
case 'sqlite':
|
||||
$sql = "SELECT name FROM sqlite_master WHERE type='table' "
|
||||
. 'UNION ALL SELECT name FROM sqlite_temp_master '
|
||||
. "WHERE type='table' ORDER BY name";
|
||||
.'UNION ALL SELECT name FROM sqlite_temp_master '
|
||||
."WHERE type='table' ORDER BY name";
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
"PDO type $type is currently not supported.", 5
|
||||
);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a value by key from the config table
|
||||
* get a value by key from the config table.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $key
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @throws PDOException
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _getConfig($key)
|
||||
{
|
||||
$row = self::_select(
|
||||
'SELECT value FROM ' . self::_sanitizeIdentifier('config') .
|
||||
' WHERE id = ?', array($key), true
|
||||
'SELECT value FROM '.self::_sanitizeIdentifier('config').
|
||||
' WHERE id = ?', [$key], true
|
||||
);
|
||||
|
||||
return $row['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* get the primary key clauses, depending on the database driver
|
||||
* get the primary key clauses, depending on the database driver.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function _getPrimaryKeyClauses($key = 'dataid')
|
||||
@ -556,101 +577,104 @@ class Database extends AbstractData
|
||||
} else {
|
||||
$main_key = ' PRIMARY KEY';
|
||||
}
|
||||
return array($main_key, $after_key);
|
||||
|
||||
return [$main_key, $after_key];
|
||||
}
|
||||
|
||||
/**
|
||||
* create the paste table
|
||||
* create the paste table.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _createPasteTable()
|
||||
{
|
||||
list($main_key, $after_key) = self::_getPrimaryKeyClauses();
|
||||
$dataType = self::$_type === 'pgsql' ? 'TEXT' : 'BLOB';
|
||||
$dataType = self::$_type === 'pgsql' ? 'TEXT' : 'BLOB';
|
||||
self::$_db->exec(
|
||||
'CREATE TABLE ' . self::_sanitizeIdentifier('paste') . ' ( ' .
|
||||
"dataid CHAR(16) NOT NULL$main_key, " .
|
||||
"data $dataType, " .
|
||||
'postdate INT, ' .
|
||||
'expiredate INT, ' .
|
||||
'opendiscussion INT, ' .
|
||||
'burnafterreading INT, ' .
|
||||
'meta TEXT, ' .
|
||||
'attachment ' . (self::$_type === 'pgsql' ? 'TEXT' : 'MEDIUMBLOB') . ', ' .
|
||||
'CREATE TABLE '.self::_sanitizeIdentifier('paste').' ( '.
|
||||
"dataid CHAR(16) NOT NULL$main_key, ".
|
||||
"data $dataType, ".
|
||||
'postdate INT, '.
|
||||
'expiredate INT, '.
|
||||
'opendiscussion INT, '.
|
||||
'burnafterreading INT, '.
|
||||
'meta TEXT, '.
|
||||
'attachment '.(self::$_type === 'pgsql' ? 'TEXT' : 'MEDIUMBLOB').', '.
|
||||
"attachmentname $dataType$after_key );"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create the paste table
|
||||
* create the paste table.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _createCommentTable()
|
||||
{
|
||||
list($main_key, $after_key) = self::_getPrimaryKeyClauses();
|
||||
$dataType = self::$_type === 'pgsql' ? 'text' : 'BLOB';
|
||||
$dataType = self::$_type === 'pgsql' ? 'text' : 'BLOB';
|
||||
self::$_db->exec(
|
||||
'CREATE TABLE ' . self::_sanitizeIdentifier('comment') . ' ( ' .
|
||||
"dataid CHAR(16) NOT NULL$main_key, " .
|
||||
'pasteid CHAR(16), ' .
|
||||
'parentid CHAR(16), ' .
|
||||
"data $dataType, " .
|
||||
"nickname $dataType, " .
|
||||
"vizhash $dataType, " .
|
||||
'CREATE TABLE '.self::_sanitizeIdentifier('comment').' ( '.
|
||||
"dataid CHAR(16) NOT NULL$main_key, ".
|
||||
'pasteid CHAR(16), '.
|
||||
'parentid CHAR(16), '.
|
||||
"data $dataType, ".
|
||||
"nickname $dataType, ".
|
||||
"vizhash $dataType, ".
|
||||
"postdate INT$after_key );"
|
||||
);
|
||||
self::$_db->exec(
|
||||
'CREATE INDEX IF NOT EXISTS comment_parent ON ' .
|
||||
self::_sanitizeIdentifier('comment') . '(pasteid);'
|
||||
'CREATE INDEX IF NOT EXISTS comment_parent ON '.
|
||||
self::_sanitizeIdentifier('comment').'(pasteid);'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create the paste table
|
||||
* create the paste table.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _createConfigTable()
|
||||
{
|
||||
list($main_key, $after_key) = self::_getPrimaryKeyClauses('id');
|
||||
self::$_db->exec(
|
||||
'CREATE TABLE ' . self::_sanitizeIdentifier('config') .
|
||||
'CREATE TABLE '.self::_sanitizeIdentifier('config').
|
||||
" ( id CHAR(16) NOT NULL$main_key, value TEXT$after_key );"
|
||||
);
|
||||
self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('config') .
|
||||
'INSERT INTO '.self::_sanitizeIdentifier('config').
|
||||
' VALUES(?,?)',
|
||||
array('VERSION', PrivateBin::VERSION)
|
||||
['VERSION', PrivateBin::VERSION]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* sanitizes identifiers
|
||||
* sanitizes identifiers.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $identifier
|
||||
*
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _sanitizeIdentifier($identifier)
|
||||
{
|
||||
return preg_replace('/[^A-Za-z0-9_]+/', '', self::$_prefix . $identifier);
|
||||
return preg_replace('/[^A-Za-z0-9_]+/', '', self::$_prefix.$identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* upgrade the database schema from an old version
|
||||
* upgrade the database schema from an old version.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $oldversion
|
||||
*
|
||||
* @param string $oldversion
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _upgradeDatabase($oldversion)
|
||||
@ -660,51 +684,51 @@ class Database extends AbstractData
|
||||
case '0.21':
|
||||
// create the meta column if necessary (pre 0.21 change)
|
||||
try {
|
||||
self::$_db->exec('SELECT meta FROM ' . self::_sanitizeIdentifier('paste') . ' LIMIT 1;');
|
||||
self::$_db->exec('SELECT meta FROM '.self::_sanitizeIdentifier('paste').' LIMIT 1;');
|
||||
} catch (PDOException $e) {
|
||||
self::$_db->exec('ALTER TABLE ' . self::_sanitizeIdentifier('paste') . ' ADD COLUMN meta TEXT;');
|
||||
self::$_db->exec('ALTER TABLE '.self::_sanitizeIdentifier('paste').' ADD COLUMN meta TEXT;');
|
||||
}
|
||||
// SQLite only allows one ALTER statement at a time...
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
||||
' ADD COLUMN attachment ' .
|
||||
(self::$_type === 'pgsql' ? 'TEXT' : 'MEDIUMBLOB') . ';'
|
||||
'ALTER TABLE '.self::_sanitizeIdentifier('paste').
|
||||
' ADD COLUMN attachment '.
|
||||
(self::$_type === 'pgsql' ? 'TEXT' : 'MEDIUMBLOB').';'
|
||||
);
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') . " ADD COLUMN attachmentname $dataType;"
|
||||
'ALTER TABLE '.self::_sanitizeIdentifier('paste')." ADD COLUMN attachmentname $dataType;"
|
||||
);
|
||||
// SQLite doesn't support MODIFY, but it allows TEXT of similar
|
||||
// size as BLOB, so there is no need to change it there
|
||||
if (self::$_type !== 'sqlite') {
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
||||
'ALTER TABLE '.self::_sanitizeIdentifier('paste').
|
||||
' ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType;'
|
||||
);
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('comment') .
|
||||
" ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType, " .
|
||||
'ALTER TABLE '.self::_sanitizeIdentifier('comment').
|
||||
" ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType, ".
|
||||
"MODIFY COLUMN nickname $dataType, MODIFY COLUMN vizhash $dataType;"
|
||||
);
|
||||
} else {
|
||||
self::$_db->exec(
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS paste_dataid ON ' .
|
||||
self::_sanitizeIdentifier('paste') . '(dataid);'
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS paste_dataid ON '.
|
||||
self::_sanitizeIdentifier('paste').'(dataid);'
|
||||
);
|
||||
self::$_db->exec(
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS comment_dataid ON ' .
|
||||
self::_sanitizeIdentifier('comment') . '(dataid);'
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS comment_dataid ON '.
|
||||
self::_sanitizeIdentifier('comment').'(dataid);'
|
||||
);
|
||||
}
|
||||
self::$_db->exec(
|
||||
'CREATE INDEX IF NOT EXISTS comment_parent ON ' .
|
||||
self::_sanitizeIdentifier('comment') . '(pasteid);'
|
||||
'CREATE INDEX IF NOT EXISTS comment_parent ON '.
|
||||
self::_sanitizeIdentifier('comment').'(pasteid);'
|
||||
);
|
||||
// no break, continue with updates for 0.22
|
||||
case '0.22':
|
||||
self::_exec(
|
||||
'UPDATE ' . self::_sanitizeIdentifier('config') .
|
||||
'UPDATE '.self::_sanitizeIdentifier('config').
|
||||
' SET value = ? WHERE id = ?',
|
||||
array('1.0', 'VERSION')
|
||||
['1.0', 'VERSION']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Data;
|
||||
|
||||
use PrivateBin\Model\Paste;
|
||||
use PrivateBin\Json;
|
||||
use PrivateBin\Model\Paste;
|
||||
|
||||
/**
|
||||
* Filesystem
|
||||
* Filesystem.
|
||||
*
|
||||
* Model for filesystem data access, implemented as a singleton.
|
||||
*/
|
||||
class Filesystem extends AbstractData
|
||||
{
|
||||
/**
|
||||
* directory where data is stored
|
||||
* directory where data is stored.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_dir = 'data/';
|
||||
|
||||
/**
|
||||
* get instance of singleton
|
||||
* get instance of singleton.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param array $options
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return Filesystem
|
||||
*/
|
||||
public static function getInstance($options = null)
|
||||
@ -46,42 +48,45 @@ class Filesystem extends AbstractData
|
||||
is_array($options) &&
|
||||
array_key_exists('dir', $options)
|
||||
) {
|
||||
self::$_dir = $options['dir'] . DIRECTORY_SEPARATOR;
|
||||
self::$_dir = $options['dir'].DIRECTORY_SEPARATOR;
|
||||
}
|
||||
// if needed initialize the singleton
|
||||
if (!(self::$_instance instanceof self)) {
|
||||
self::$_instance = new self;
|
||||
self::$_instance = new self();
|
||||
self::_init();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param array $paste
|
||||
* @param string $pasteid
|
||||
* @param array $paste
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function create($pasteid, $paste)
|
||||
{
|
||||
$storagedir = self::_dataid2path($pasteid);
|
||||
if (is_file($storagedir . $pasteid)) {
|
||||
if (is_file($storagedir.$pasteid)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_dir($storagedir)) {
|
||||
mkdir($storagedir, 0700, true);
|
||||
}
|
||||
return (bool) file_put_contents($storagedir . $pasteid, Json::encode($paste));
|
||||
|
||||
return (bool) file_put_contents($storagedir.$pasteid, Json::encode($paste));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return stdClass|false
|
||||
*/
|
||||
public function read($pasteid)
|
||||
@ -90,7 +95,7 @@ class Filesystem extends AbstractData
|
||||
return false;
|
||||
}
|
||||
$paste = json_decode(
|
||||
file_get_contents(self::_dataid2path($pasteid) . $pasteid)
|
||||
file_get_contents(self::_dataid2path($pasteid).$pasteid)
|
||||
);
|
||||
if (property_exists($paste->meta, 'attachment')) {
|
||||
$paste->attachment = $paste->meta->attachment;
|
||||
@ -100,14 +105,15 @@ class Filesystem extends AbstractData
|
||||
unset($paste->meta->attachmentname);
|
||||
}
|
||||
}
|
||||
|
||||
return $paste;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a paste and its discussion.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete($pasteid)
|
||||
@ -115,8 +121,8 @@ class Filesystem extends AbstractData
|
||||
$pastedir = self::_dataid2path($pasteid);
|
||||
if (is_dir($pastedir)) {
|
||||
// Delete the paste itself.
|
||||
if (is_file($pastedir . $pasteid)) {
|
||||
unlink($pastedir . $pasteid);
|
||||
if (is_file($pastedir.$pasteid)) {
|
||||
unlink($pastedir.$pasteid);
|
||||
}
|
||||
|
||||
// Delete discussion if it exists.
|
||||
@ -125,8 +131,8 @@ class Filesystem extends AbstractData
|
||||
// Delete all files in discussion directory
|
||||
$dir = dir($discdir);
|
||||
while (false !== ($filename = $dir->read())) {
|
||||
if (is_file($discdir . $filename)) {
|
||||
unlink($discdir . $filename);
|
||||
if (is_file($discdir.$filename)) {
|
||||
unlink($discdir.$filename);
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
@ -138,50 +144,52 @@ class Filesystem extends AbstractData
|
||||
/**
|
||||
* Test if a paste exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($pasteid)
|
||||
{
|
||||
return is_file(self::_dataid2path($pasteid) . $pasteid);
|
||||
return is_file(self::_dataid2path($pasteid).$pasteid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a comment in a paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param array $comment
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param array $comment
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function createComment($pasteid, $parentid, $commentid, $comment)
|
||||
{
|
||||
$storagedir = self::_dataid2discussionpath($pasteid);
|
||||
$filename = $pasteid . '.' . $commentid . '.' . $parentid;
|
||||
if (is_file($storagedir . $filename)) {
|
||||
$filename = $pasteid.'.'.$commentid.'.'.$parentid;
|
||||
if (is_file($storagedir.$filename)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_dir($storagedir)) {
|
||||
mkdir($storagedir, 0700, true);
|
||||
}
|
||||
return (bool) file_put_contents($storagedir . $filename, Json::encode($comment));
|
||||
|
||||
return (bool) file_put_contents($storagedir.$filename, Json::encode($comment));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all comments of paste.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $pasteid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function readComments($pasteid)
|
||||
{
|
||||
$comments = array();
|
||||
$discdir = self::_dataid2discussionpath($pasteid);
|
||||
$comments = [];
|
||||
$discdir = self::_dataid2discussionpath($pasteid);
|
||||
if (is_dir($discdir)) {
|
||||
// Delete all files in discussion directory
|
||||
$dir = dir($discdir);
|
||||
@ -190,15 +198,15 @@ class Filesystem extends AbstractData
|
||||
// - pasteid is the paste this reply belongs to.
|
||||
// - commentid is the comment identifier itself.
|
||||
// - parentid is the comment this comment replies to (It can be pasteid)
|
||||
if (is_file($discdir . $filename)) {
|
||||
$comment = json_decode(file_get_contents($discdir . $filename));
|
||||
$items = explode('.', $filename);
|
||||
if (is_file($discdir.$filename)) {
|
||||
$comment = json_decode(file_get_contents($discdir.$filename));
|
||||
$items = explode('.', $filename);
|
||||
// Add some meta information not contained in file.
|
||||
$comment->id = $items[1];
|
||||
$comment->id = $items[1];
|
||||
$comment->parentid = $items[2];
|
||||
|
||||
// Store in array
|
||||
$key = $this->getOpenSlot($comments, (int) $comment->meta->postdate);
|
||||
$key = $this->getOpenSlot($comments, (int) $comment->meta->postdate);
|
||||
$comments[$key] = $comment;
|
||||
}
|
||||
}
|
||||
@ -207,36 +215,37 @@ class Filesystem extends AbstractData
|
||||
// Sort comments by date, oldest first.
|
||||
ksort($comments);
|
||||
}
|
||||
|
||||
return $comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a comment exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
* @param string $pasteid
|
||||
* @param string $parentid
|
||||
* @param string $commentid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function existsComment($pasteid, $parentid, $commentid)
|
||||
{
|
||||
return is_file(
|
||||
self::_dataid2discussionpath($pasteid) .
|
||||
$pasteid . '.' . $commentid . '.' . $parentid
|
||||
self::_dataid2discussionpath($pasteid).
|
||||
$pasteid.'.'.$commentid.'.'.$parentid
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns up to batch size number of paste ids that have expired
|
||||
* Returns up to batch size number of paste ids that have expired.
|
||||
*
|
||||
* @param int $batchsize
|
||||
*
|
||||
* @access private
|
||||
* @param int $batchsize
|
||||
* @return array
|
||||
*/
|
||||
protected function _getExpiredPastes($batchsize)
|
||||
{
|
||||
$pastes = array();
|
||||
$pastes = [];
|
||||
$firstLevel = array_filter(
|
||||
scandir(self::$_dir),
|
||||
'self::_isFirstLevelDir'
|
||||
@ -244,9 +253,9 @@ class Filesystem extends AbstractData
|
||||
if (count($firstLevel) > 0) {
|
||||
// try at most 10 times the $batchsize pastes before giving up
|
||||
for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) {
|
||||
$firstKey = array_rand($firstLevel);
|
||||
$firstKey = array_rand($firstLevel);
|
||||
$secondLevel = array_filter(
|
||||
scandir(self::$_dir . $firstLevel[$firstKey]),
|
||||
scandir(self::$_dir.$firstLevel[$firstKey]),
|
||||
'self::_isSecondLevelDir'
|
||||
);
|
||||
|
||||
@ -257,8 +266,8 @@ class Filesystem extends AbstractData
|
||||
}
|
||||
|
||||
$secondKey = array_rand($secondLevel);
|
||||
$path = self::$_dir . $firstLevel[$firstKey] .
|
||||
DIRECTORY_SEPARATOR . $secondLevel[$secondKey];
|
||||
$path = self::$_dir.$firstLevel[$firstKey].
|
||||
DIRECTORY_SEPARATOR.$secondLevel[$secondKey];
|
||||
if (!is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
@ -270,7 +279,7 @@ class Filesystem extends AbstractData
|
||||
continue;
|
||||
}
|
||||
$thirdKey = array_rand($thirdLevel);
|
||||
$pasteid = $thirdLevel[$thirdKey];
|
||||
$pasteid = $thirdLevel[$thirdKey];
|
||||
if (in_array($pasteid, $pastes)) {
|
||||
continue;
|
||||
}
|
||||
@ -289,14 +298,15 @@ class Filesystem extends AbstractData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $pastes;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize privatebin
|
||||
* initialize privatebin.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _init()
|
||||
@ -306,11 +316,11 @@ class Filesystem extends AbstractData
|
||||
mkdir(self::$_dir, 0700);
|
||||
}
|
||||
// Create .htaccess file if it does not exist.
|
||||
if (!is_file(self::$_dir . '.htaccess')) {
|
||||
if (!is_file(self::$_dir.'.htaccess')) {
|
||||
file_put_contents(
|
||||
self::$_dir . '.htaccess',
|
||||
'Allow from none' . PHP_EOL .
|
||||
'Deny from all' . PHP_EOL
|
||||
self::$_dir.'.htaccess',
|
||||
'Allow from none'.PHP_EOL.
|
||||
'Deny from all'.PHP_EOL
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -325,15 +335,16 @@ class Filesystem extends AbstractData
|
||||
*
|
||||
* eg. input 'e3570978f9e4aa90' --> output 'data/e3/57/'
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $dataid
|
||||
*
|
||||
* @param string $dataid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _dataid2path($dataid)
|
||||
{
|
||||
return self::$_dir . substr($dataid, 0, 2) . DIRECTORY_SEPARATOR .
|
||||
substr($dataid, 2, 2) . DIRECTORY_SEPARATOR;
|
||||
return self::$_dir.substr($dataid, 0, 2).DIRECTORY_SEPARATOR.
|
||||
substr($dataid, 2, 2).DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -341,37 +352,40 @@ class Filesystem extends AbstractData
|
||||
*
|
||||
* eg. input 'e3570978f9e4aa90' --> output 'data/e3/57/e3570978f9e4aa90.discussion/'
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $dataid
|
||||
*
|
||||
* @param string $dataid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function _dataid2discussionpath($dataid)
|
||||
{
|
||||
return self::_dataid2path($dataid) . $dataid .
|
||||
'.discussion' . DIRECTORY_SEPARATOR;
|
||||
return self::_dataid2path($dataid).$dataid.
|
||||
'.discussion'.DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given element is a valid first level directory.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $element
|
||||
*
|
||||
* @param string $element
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function _isFirstLevelDir($element)
|
||||
{
|
||||
return self::_isSecondLevelDir($element) &&
|
||||
is_dir(self::$_dir . DIRECTORY_SEPARATOR . $element);
|
||||
is_dir(self::$_dir.DIRECTORY_SEPARATOR.$element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given element is a valid second level directory.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @param string $element
|
||||
*
|
||||
* @param string $element
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function _isSecondLevelDir($element)
|
||||
|
@ -1,33 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
use PrivateBin\I18n;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Filter
|
||||
* Filter.
|
||||
*
|
||||
* Provides data filtering functions.
|
||||
*/
|
||||
class Filter
|
||||
{
|
||||
/**
|
||||
* strips slashes deeply
|
||||
* strips slashes deeply.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param mixed $value
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function stripslashesDeep($value)
|
||||
@ -38,14 +39,16 @@ class Filter
|
||||
}
|
||||
|
||||
/**
|
||||
* format a given time string into a human readable label (localized)
|
||||
* format a given time string into a human readable label (localized).
|
||||
*
|
||||
* accepts times in the format "[integer][time unit]"
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $time
|
||||
*
|
||||
* @param string $time
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function formatHumanReadableTime($time)
|
||||
@ -63,36 +66,40 @@ class Filter
|
||||
default:
|
||||
$unit = rtrim($matches[2], 's');
|
||||
}
|
||||
return I18n::_(array('%d ' . $unit, '%d ' . $unit . 's'), (int) $matches[1]);
|
||||
|
||||
return I18n::_(['%d '.$unit, '%d '.$unit.'s'], (int) $matches[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* format a given number of bytes in IEC 80000-13:2008 notation (localized)
|
||||
* format a given number of bytes in IEC 80000-13:2008 notation (localized).
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param int $size
|
||||
*
|
||||
* @param int $size
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function formatHumanReadableSize($size)
|
||||
{
|
||||
$iec = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB');
|
||||
$i = 0;
|
||||
$iec = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
||||
$i = 0;
|
||||
while (($size / 1024) >= 1) {
|
||||
$size = $size / 1024;
|
||||
$i++;
|
||||
}
|
||||
return number_format($size, ($i ? 2 : 0), '.', ' ') . ' ' . I18n::_($iec[$i]);
|
||||
|
||||
return number_format($size, ($i ? 2 : 0), '.', ' ').' '.I18n::_($iec[$i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* fixed time string comparison operation to prevent timing attacks
|
||||
* https://crackstation.net/hashing-security.htm?=rd#slowequals
|
||||
* https://crackstation.net/hashing-security.htm?=rd#slowequals.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function slowEquals($a, $b)
|
||||
@ -101,6 +108,7 @@ class Filter
|
||||
for ($i = 0; $i < strlen($a) && $i < strlen($b); $i++) {
|
||||
$diff |= ord($a[$i]) ^ ord($b[$i]);
|
||||
}
|
||||
|
||||
return $diff === 0;
|
||||
}
|
||||
}
|
||||
|
168
lib/I18n.php
168
lib/I18n.php
@ -1,85 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
/**
|
||||
* I18n
|
||||
* I18n.
|
||||
*
|
||||
* provides internationalization tools like translation, browser language detection, etc.
|
||||
*/
|
||||
class I18n
|
||||
{
|
||||
/**
|
||||
* language
|
||||
* language.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $_language = 'en';
|
||||
|
||||
/**
|
||||
* language fallback
|
||||
* language fallback.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $_languageFallback = 'en';
|
||||
|
||||
/**
|
||||
* language labels
|
||||
* language labels.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @var array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_languageLabels = array();
|
||||
protected static $_languageLabels = [];
|
||||
|
||||
/**
|
||||
* available languages
|
||||
* available languages.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @var array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_availableLanguages = array();
|
||||
protected static $_availableLanguages = [];
|
||||
|
||||
/**
|
||||
* path to language files
|
||||
* path to language files.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $_path = '';
|
||||
|
||||
/**
|
||||
* translation cache
|
||||
* translation cache.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @var array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_translations = array();
|
||||
protected static $_translations = [];
|
||||
|
||||
/**
|
||||
* translate a string, alias for translate()
|
||||
* translate a string, alias for translate().
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $messageId
|
||||
* @param mixed $args one or multiple parameters injected into placeholders
|
||||
*
|
||||
* @param string $messageId
|
||||
* @param mixed $args one or multiple parameters injected into placeholders
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function _($messageId)
|
||||
@ -88,12 +90,13 @@ class I18n
|
||||
}
|
||||
|
||||
/**
|
||||
* translate a string
|
||||
* translate a string.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $messageId
|
||||
* @param mixed $args one or multiple parameters injected into placeholders
|
||||
*
|
||||
* @param string $messageId
|
||||
* @param mixed $args one or multiple parameters injected into placeholders
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function translate($messageId)
|
||||
@ -114,8 +117,8 @@ class I18n
|
||||
$args = func_get_args();
|
||||
if (is_array(self::$_translations[$messageId])) {
|
||||
$number = (int) $args[1];
|
||||
$key = self::_getPluralForm($number);
|
||||
$max = count(self::$_translations[$messageId]) - 1;
|
||||
$key = self::_getPluralForm($number);
|
||||
$max = count(self::$_translations[$messageId]) - 1;
|
||||
if ($key > $max) {
|
||||
$key = $max;
|
||||
}
|
||||
@ -125,16 +128,17 @@ class I18n
|
||||
} else {
|
||||
$args[0] = self::$_translations[$messageId];
|
||||
}
|
||||
|
||||
return call_user_func_array('sprintf', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* loads translations
|
||||
* loads translations.
|
||||
*
|
||||
* From: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function loadTranslations()
|
||||
@ -153,18 +157,18 @@ class I18n
|
||||
}
|
||||
|
||||
// load translations
|
||||
self::$_language = $match;
|
||||
self::$_translations = ($match == 'en') ? array() : json_decode(
|
||||
file_get_contents(self::_getPath($match . '.json')),
|
||||
self::$_language = $match;
|
||||
self::$_translations = ($match == 'en') ? [] : json_decode(
|
||||
file_get_contents(self::_getPath($match.'.json')),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get list of available translations based on files found
|
||||
* get list of available translations based on files found.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAvailableLanguages()
|
||||
@ -178,21 +182,22 @@ class I18n
|
||||
}
|
||||
self::$_availableLanguages[] = 'en';
|
||||
}
|
||||
|
||||
return self::$_availableLanguages;
|
||||
}
|
||||
|
||||
/**
|
||||
* detect the clients supported languages and return them ordered by preference
|
||||
* detect the clients supported languages and return them ordered by preference.
|
||||
*
|
||||
* From: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getBrowserLanguages()
|
||||
{
|
||||
$languages = array();
|
||||
$languages = [];
|
||||
if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
|
||||
$languageRanges = explode(',', trim($_SERVER['HTTP_ACCEPT_LANGUAGE']));
|
||||
foreach ($languageRanges as $languageRange) {
|
||||
@ -206,21 +211,22 @@ class I18n
|
||||
$match[2] = (string) floatval($match[2]);
|
||||
}
|
||||
if (!isset($languages[$match[2]])) {
|
||||
$languages[$match[2]] = array();
|
||||
$languages[$match[2]] = [];
|
||||
}
|
||||
$languages[$match[2]][] = strtolower($match[1]);
|
||||
}
|
||||
}
|
||||
krsort($languages);
|
||||
}
|
||||
|
||||
return $languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* get currently loaded language
|
||||
* get currently loaded language.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getLanguage()
|
||||
@ -229,16 +235,17 @@ class I18n
|
||||
}
|
||||
|
||||
/**
|
||||
* get list of language labels
|
||||
* get list of language labels.
|
||||
*
|
||||
* Only for given language codes, otherwise all labels.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param array $languages
|
||||
*
|
||||
* @param array $languages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getLanguageLabels($languages = array())
|
||||
public static function getLanguageLabels($languages = [])
|
||||
{
|
||||
$file = self::_getPath('languages.json');
|
||||
if (count(self::$_languageLabels) == 0 && is_readable($file)) {
|
||||
@ -247,15 +254,17 @@ class I18n
|
||||
if (count($languages) == 0) {
|
||||
return self::$_languageLabels;
|
||||
}
|
||||
|
||||
return array_intersect_key(self::$_languageLabels, array_flip($languages));
|
||||
}
|
||||
|
||||
/**
|
||||
* set the default language
|
||||
* set the default language.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $lang
|
||||
*
|
||||
* @param string $lang
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setLanguageFallback($lang)
|
||||
@ -266,29 +275,32 @@ class I18n
|
||||
}
|
||||
|
||||
/**
|
||||
* get language file path
|
||||
* get language file path.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @param string $file
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getPath($file = '')
|
||||
{
|
||||
if (strlen(self::$_path) == 0) {
|
||||
self::$_path = PUBLIC_PATH . DIRECTORY_SEPARATOR . 'i18n';
|
||||
self::$_path = PUBLIC_PATH.DIRECTORY_SEPARATOR.'i18n';
|
||||
}
|
||||
return self::$_path . (strlen($file) ? DIRECTORY_SEPARATOR . $file : '');
|
||||
|
||||
return self::$_path.(strlen($file) ? DIRECTORY_SEPARATOR.$file : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* determines the plural form to use based on current language and given number
|
||||
* determines the plural form to use based on current language and given number.
|
||||
*
|
||||
* From: http://localization-guide.readthedocs.org/en/latest/l10n/pluralforms.html
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @param int $n
|
||||
*
|
||||
* @param int $n
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected static function _getPluralForm($n)
|
||||
@ -296,30 +308,31 @@ class I18n
|
||||
switch (self::$_language) {
|
||||
case 'fr':
|
||||
case 'zh':
|
||||
return ($n > 1 ? 1 : 0);
|
||||
return $n > 1 ? 1 : 0;
|
||||
case 'pl':
|
||||
return ($n == 1 ? 0 : $n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
|
||||
return $n == 1 ? 0 : $n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2;
|
||||
// en, de
|
||||
default:
|
||||
return ($n != 1 ? 1 : 0);
|
||||
return $n != 1 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* compares two language preference arrays and returns the preferred match
|
||||
* compares two language preference arrays and returns the preferred match.
|
||||
*
|
||||
* From: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @param array $acceptedLanguages
|
||||
* @param array $availableLanguages
|
||||
*
|
||||
* @param array $acceptedLanguages
|
||||
* @param array $availableLanguages
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getMatchingLanguage($acceptedLanguages, $availableLanguages)
|
||||
{
|
||||
$matches = array();
|
||||
$any = false;
|
||||
$matches = [];
|
||||
$any = false;
|
||||
foreach ($acceptedLanguages as $acceptedQuality => $acceptedValues) {
|
||||
$acceptedQuality = floatval($acceptedQuality);
|
||||
if ($acceptedQuality === 0.0) {
|
||||
@ -335,7 +348,7 @@ class I18n
|
||||
if ($matchingGrade > 0) {
|
||||
$q = (string) ($acceptedQuality * $availableQuality * $matchingGrade);
|
||||
if (!isset($matches[$q])) {
|
||||
$matches[$q] = array();
|
||||
$matches[$q] = [];
|
||||
}
|
||||
if (!in_array($availableValue, $matches[$q])) {
|
||||
$matches[$q][] = $availableValue;
|
||||
@ -354,18 +367,20 @@ class I18n
|
||||
}
|
||||
krsort($matches);
|
||||
$topmatches = current($matches);
|
||||
|
||||
return current($topmatches);
|
||||
}
|
||||
|
||||
/**
|
||||
* compare two language IDs and return the degree they match
|
||||
* compare two language IDs and return the degree they match.
|
||||
*
|
||||
* From: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
protected static function _matchLanguage($a, $b)
|
||||
@ -377,6 +392,7 @@ class I18n
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $i === 0 ? 0 : (float) $i / count($a);
|
||||
}
|
||||
}
|
||||
|
21
lib/Json.php
21
lib/Json.php
@ -1,48 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Json
|
||||
* Json.
|
||||
*
|
||||
* Provides JSON functions in an object oriented way.
|
||||
*/
|
||||
class Json
|
||||
{
|
||||
/**
|
||||
* Returns a string containing the JSON representation of the given input
|
||||
* Returns a string containing the JSON representation of the given input.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param mixed $input
|
||||
*
|
||||
* @param mixed $input
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($input)
|
||||
{
|
||||
$jsonString = json_encode($input);
|
||||
$errorCode = json_last_error();
|
||||
$errorCode = json_last_error();
|
||||
if ($errorCode === JSON_ERROR_NONE) {
|
||||
return $jsonString;
|
||||
}
|
||||
|
||||
$message = 'A JSON error occurred';
|
||||
if (function_exists('json_last_error_msg')) {
|
||||
$message .= ': ' . json_last_error_msg();
|
||||
$message .= ': '.json_last_error_msg();
|
||||
}
|
||||
$message .= ' (' . $errorCode . ')';
|
||||
$message .= ' ('.$errorCode.')';
|
||||
throw new Exception($message, 90);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
use PrivateBin\Data;
|
||||
use PrivateBin\Model\Paste;
|
||||
use PrivateBin\Persistence\PurgeLimiter;
|
||||
|
||||
/**
|
||||
* Model
|
||||
* Model.
|
||||
*
|
||||
* Factory of PrivateBin instance models.
|
||||
*/
|
||||
@ -41,6 +41,7 @@ class Model
|
||||
* Factory constructor.
|
||||
*
|
||||
* @param configuration $conf
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Configuration $conf)
|
||||
@ -52,6 +53,7 @@ class Model
|
||||
* Get a paste, optionally a specific instance.
|
||||
*
|
||||
* @param string $pasteId
|
||||
*
|
||||
* @return Paste
|
||||
*/
|
||||
public function getPaste($pasteId = null)
|
||||
@ -60,6 +62,7 @@ class Model
|
||||
if ($pasteId !== null) {
|
||||
$paste->setId($pasteId);
|
||||
}
|
||||
|
||||
return $paste;
|
||||
}
|
||||
|
||||
@ -77,7 +80,7 @@ class Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets, and creates if neccessary, a store object
|
||||
* Gets, and creates if neccessary, a store object.
|
||||
*
|
||||
* @return AbstractData
|
||||
*/
|
||||
@ -85,10 +88,11 @@ class Model
|
||||
{
|
||||
if ($this->_store === null) {
|
||||
$this->_store = forward_static_call(
|
||||
'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model') . '::getInstance',
|
||||
'PrivateBin\\Data\\'.$this->_conf->getKey('class', 'model').'::getInstance',
|
||||
$this->_conf->getSection('model_options')
|
||||
);
|
||||
}
|
||||
|
||||
return $this->_store;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Model;
|
||||
|
||||
use Exception;
|
||||
use PrivateBin\Configuration;
|
||||
use PrivateBin\Data\AbstractData;
|
||||
use PrivateBin\Sjcl;
|
||||
use Exception;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* AbstractModel
|
||||
* AbstractModel.
|
||||
*
|
||||
* Abstract model for PrivateBin objects.
|
||||
*/
|
||||
@ -28,7 +29,6 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Instance ID.
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $_id = '';
|
||||
@ -36,7 +36,6 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Instance data.
|
||||
*
|
||||
* @access protected
|
||||
* @var stdClass
|
||||
*/
|
||||
protected $_data;
|
||||
@ -44,7 +43,6 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Configuration.
|
||||
*
|
||||
* @access protected
|
||||
* @var Configuration
|
||||
*/
|
||||
protected $_conf;
|
||||
@ -52,7 +50,6 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Data storage.
|
||||
*
|
||||
* @access protected
|
||||
* @var AbstractData
|
||||
*/
|
||||
protected $_store;
|
||||
@ -60,23 +57,22 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Instance constructor.
|
||||
*
|
||||
* @access public
|
||||
* @param Configuration $configuration
|
||||
* @param AbstractData $storage
|
||||
* @param Configuration $configuration
|
||||
* @param AbstractData $storage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Configuration $configuration, AbstractData $storage)
|
||||
{
|
||||
$this->_conf = $configuration;
|
||||
$this->_store = $storage;
|
||||
$this->_data = new stdClass;
|
||||
$this->_data->meta = new stdClass;
|
||||
$this->_conf = $configuration;
|
||||
$this->_store = $storage;
|
||||
$this->_data = new stdClass();
|
||||
$this->_data->meta = new stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ID.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
@ -87,9 +83,10 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Set ID.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setId($id)
|
||||
@ -103,9 +100,10 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Set data and recalculate ID.
|
||||
*
|
||||
* @access public
|
||||
* @param string $data
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setData($data)
|
||||
@ -123,7 +121,6 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Get instance data.
|
||||
*
|
||||
* @access public
|
||||
* @return stdClass
|
||||
*/
|
||||
abstract public function get();
|
||||
@ -131,8 +128,8 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Store the instance's data.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function store();
|
||||
@ -140,8 +137,8 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Delete the current instance.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function delete();
|
||||
@ -149,7 +146,6 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Test if current instance exists in store.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function exists();
|
||||
@ -157,9 +153,10 @@ abstract class AbstractModel
|
||||
/**
|
||||
* Validate ID.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $id
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidId($id)
|
||||
|
@ -1,25 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Model;
|
||||
|
||||
use PrivateBin\Sjcl;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
use PrivateBin\Vizhash16x16;
|
||||
use Identicon\Identicon;
|
||||
use Exception;
|
||||
use Identicon\Identicon;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
use PrivateBin\Sjcl;
|
||||
use PrivateBin\Vizhash16x16;
|
||||
|
||||
/**
|
||||
* Comment
|
||||
* Comment.
|
||||
*
|
||||
* Model of a PrivateBin comment.
|
||||
*/
|
||||
@ -28,7 +29,6 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Instance's parent.
|
||||
*
|
||||
* @access private
|
||||
* @var Paste
|
||||
*/
|
||||
private $_paste;
|
||||
@ -36,8 +36,8 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Get comment data.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function get()
|
||||
@ -53,14 +53,15 @@ class Comment extends AbstractModel
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the comment's data.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function store()
|
||||
@ -99,8 +100,8 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Delete the comment.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
@ -111,7 +112,6 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Test if comment exists in store.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
@ -126,21 +126,21 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Set paste.
|
||||
*
|
||||
* @access public
|
||||
* @param Paste $paste
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPaste(Paste $paste)
|
||||
{
|
||||
$this->_paste = $paste;
|
||||
$this->_paste = $paste;
|
||||
$this->_data->meta->pasteid = $paste->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paste.
|
||||
*
|
||||
* @access public
|
||||
* @return Paste
|
||||
*/
|
||||
public function getPaste()
|
||||
@ -151,9 +151,10 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Set parent ID.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setParentId($id)
|
||||
@ -167,7 +168,6 @@ class Comment extends AbstractModel
|
||||
/**
|
||||
* Get parent ID.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getParentId()
|
||||
@ -175,15 +175,17 @@ class Comment extends AbstractModel
|
||||
if (!property_exists($this->_data->meta, 'parentid')) {
|
||||
$this->_data->meta->parentid = '';
|
||||
}
|
||||
|
||||
return $this->_data->meta->parentid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set nickname.
|
||||
*
|
||||
* @access public
|
||||
* @param string $nickname
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setNickname($nickname)
|
||||
@ -199,13 +201,13 @@ class Comment extends AbstractModel
|
||||
$icon = $this->_conf->getKey('icon');
|
||||
if ($icon != 'none') {
|
||||
$pngdata = '';
|
||||
$hmac = TrafficLimiter::getHash();
|
||||
$hmac = TrafficLimiter::getHash();
|
||||
if ($icon == 'identicon') {
|
||||
$identicon = new Identicon();
|
||||
$pngdata = $identicon->getImageDataUri($hmac, 16);
|
||||
$pngdata = $identicon->getImageDataUri($hmac, 16);
|
||||
} elseif ($icon == 'vizhash') {
|
||||
$vh = new Vizhash16x16();
|
||||
$pngdata = 'data:image/png;base64,' . base64_encode(
|
||||
$vh = new Vizhash16x16();
|
||||
$pngdata = 'data:image/png;base64,'.base64_encode(
|
||||
$vh->generate($hmac)
|
||||
);
|
||||
}
|
||||
|
@ -1,24 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Model;
|
||||
|
||||
use PrivateBin\PrivateBin;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Sjcl;
|
||||
use Exception;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\PrivateBin;
|
||||
use PrivateBin\Sjcl;
|
||||
|
||||
/**
|
||||
* Paste
|
||||
* Paste.
|
||||
*
|
||||
* Model of a PrivateBin paste.
|
||||
*/
|
||||
@ -27,8 +28,8 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Get paste data.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function get()
|
||||
@ -62,19 +63,20 @@ class Paste extends AbstractModel
|
||||
if (!property_exists($data->meta, 'salt')) {
|
||||
$data->meta->salt = ServerSalt::get();
|
||||
}
|
||||
$data->comments = array_values($this->getComments());
|
||||
$data->comment_count = count($data->comments);
|
||||
$data->comments = array_values($this->getComments());
|
||||
$data->comment_count = count($data->comments);
|
||||
$data->comment_offset = 0;
|
||||
$data->{'@context'} = 'js/paste.jsonld';
|
||||
$this->_data = $data;
|
||||
$data->{'@context'} = 'js/paste.jsonld';
|
||||
$this->_data = $data;
|
||||
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the paste's data.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function store()
|
||||
@ -85,7 +87,7 @@ class Paste extends AbstractModel
|
||||
}
|
||||
|
||||
$this->_data->meta->postdate = time();
|
||||
$this->_data->meta->salt = serversalt::generate();
|
||||
$this->_data->meta->salt = serversalt::generate();
|
||||
|
||||
// store paste
|
||||
if (
|
||||
@ -101,8 +103,8 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Delete the paste.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
@ -113,7 +115,6 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Test if paste exists in store.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
@ -124,10 +125,11 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Get a comment, optionally a specific instance.
|
||||
*
|
||||
* @access public
|
||||
* @param string $parentId
|
||||
* @param string $commentId
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return Comment
|
||||
*/
|
||||
public function getComment($parentId, $commentId = null)
|
||||
@ -141,13 +143,13 @@ class Paste extends AbstractModel
|
||||
if ($commentId !== null) {
|
||||
$comment->setId($commentId);
|
||||
}
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all comments, if any.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getComments()
|
||||
@ -162,7 +164,6 @@ class Paste extends AbstractModel
|
||||
* The paste can be deleted by calling:
|
||||
* http://example.com/privatebin/?pasteid=<pasteid>&deletetoken=<deletetoken>
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getDeleteToken()
|
||||
@ -170,6 +171,7 @@ class Paste extends AbstractModel
|
||||
if (!property_exists($this->_data->meta, 'salt')) {
|
||||
$this->get();
|
||||
}
|
||||
|
||||
return hash_hmac(
|
||||
$this->_conf->getKey('zerobincompatibility') ? 'sha1' : 'sha256',
|
||||
$this->getId(),
|
||||
@ -180,9 +182,10 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Set paste's attachment.
|
||||
*
|
||||
* @access public
|
||||
* @param string $attachment
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAttachment($attachment)
|
||||
@ -196,9 +199,10 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Set paste's attachment name.
|
||||
*
|
||||
* @access public
|
||||
* @param string $attachmentname
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAttachmentName($attachmentname)
|
||||
@ -212,8 +216,8 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Set paste expiration.
|
||||
*
|
||||
* @access public
|
||||
* @param string $expiration
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setExpiration($expiration)
|
||||
@ -233,9 +237,10 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Set paste's burn-after-reading type.
|
||||
*
|
||||
* @access public
|
||||
* @param string $burnafterreading
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setBurnafterreading($burnafterreading = '1')
|
||||
@ -247,16 +252,17 @@ class Paste extends AbstractModel
|
||||
throw new Exception('Invalid data.', 73);
|
||||
}
|
||||
$this->_data->meta->burnafterreading = true;
|
||||
$this->_data->meta->opendiscussion = false;
|
||||
$this->_data->meta->opendiscussion = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set paste's discussion state.
|
||||
*
|
||||
* @access public
|
||||
* @param string $opendiscussion
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOpendiscussion($opendiscussion = '1')
|
||||
@ -278,9 +284,10 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Set paste's format.
|
||||
*
|
||||
* @access public
|
||||
* @param string $format
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter($format)
|
||||
@ -294,8 +301,8 @@ class Paste extends AbstractModel
|
||||
/**
|
||||
* Check if paste is of burn-after-reading type.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBurnafterreading()
|
||||
@ -303,16 +310,16 @@ class Paste extends AbstractModel
|
||||
if (!property_exists($this->_data, 'data')) {
|
||||
$this->get();
|
||||
}
|
||||
|
||||
return property_exists($this->_data->meta, 'burnafterreading') &&
|
||||
$this->_data->meta->burnafterreading === true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if paste has discussions enabled.
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOpendiscussion()
|
||||
@ -320,6 +327,7 @@ class Paste extends AbstractModel
|
||||
if (!property_exists($this->_data, 'data')) {
|
||||
$this->get();
|
||||
}
|
||||
|
||||
return property_exists($this->_data->meta, 'opendiscussion') &&
|
||||
$this->_data->meta->opendiscussion === true;
|
||||
}
|
||||
|
@ -1,41 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Persistence;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* AbstractPersistence
|
||||
* AbstractPersistence.
|
||||
*
|
||||
* persists data in PHP files
|
||||
*/
|
||||
abstract class AbstractPersistence
|
||||
{
|
||||
/**
|
||||
* path in which to persist something
|
||||
* path in which to persist something.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_path = 'data';
|
||||
|
||||
/**
|
||||
* set the path
|
||||
* set the path.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $path
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setPath($path)
|
||||
@ -44,42 +46,46 @@ abstract class AbstractPersistence
|
||||
}
|
||||
|
||||
/**
|
||||
* get the path
|
||||
* get the path.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $filename
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getPath($filename = null)
|
||||
{
|
||||
if (strlen($filename)) {
|
||||
return self::$_path . DIRECTORY_SEPARATOR . $filename;
|
||||
return self::$_path.DIRECTORY_SEPARATOR.$filename;
|
||||
} else {
|
||||
return self::$_path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the file exists
|
||||
* checks if the file exists.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @param string $filename
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function _exists($filename)
|
||||
{
|
||||
self::_initialize();
|
||||
return is_file(self::$_path . DIRECTORY_SEPARATOR . $filename);
|
||||
|
||||
return is_file(self::$_path.DIRECTORY_SEPARATOR.$filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* prepares path for storage
|
||||
* prepares path for storage.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function _initialize()
|
||||
@ -87,42 +93,44 @@ abstract class AbstractPersistence
|
||||
// Create storage directory if it does not exist.
|
||||
if (!is_dir(self::$_path)) {
|
||||
if (!@mkdir(self::$_path)) {
|
||||
throw new Exception('unable to create directory ' . self::$_path, 10);
|
||||
throw new Exception('unable to create directory '.self::$_path, 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Create .htaccess file if it does not exist.
|
||||
$file = self::$_path . DIRECTORY_SEPARATOR . '.htaccess';
|
||||
$file = self::$_path.DIRECTORY_SEPARATOR.'.htaccess';
|
||||
if (!is_file($file)) {
|
||||
$writtenBytes = @file_put_contents(
|
||||
$file,
|
||||
'Allow from none' . PHP_EOL .
|
||||
'Deny from all' . PHP_EOL,
|
||||
'Allow from none'.PHP_EOL.
|
||||
'Deny from all'.PHP_EOL,
|
||||
LOCK_EX
|
||||
);
|
||||
if ($writtenBytes === false || $writtenBytes < 30) {
|
||||
throw new Exception('unable to write to file ' . $file, 11);
|
||||
throw new Exception('unable to write to file '.$file, 11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* store the data
|
||||
* store the data.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
* @param string $filename
|
||||
* @param string $data
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $data
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function _store($filename, $data)
|
||||
{
|
||||
self::_initialize();
|
||||
$file = self::$_path . DIRECTORY_SEPARATOR . $filename;
|
||||
$file = self::$_path.DIRECTORY_SEPARATOR.$filename;
|
||||
$writtenBytes = @file_put_contents($file, $data, LOCK_EX);
|
||||
if ($writtenBytes === false || $writtenBytes < strlen($data)) {
|
||||
throw new Exception('unable to write to file ' . $file, 13);
|
||||
throw new Exception('unable to write to file '.$file, 13);
|
||||
}
|
||||
@chmod($file, 0640); // protect file access
|
||||
return $file;
|
||||
|
@ -1,41 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Persistence;
|
||||
|
||||
use PrivateBin\Configuration;
|
||||
|
||||
/**
|
||||
* PurgeLimiter
|
||||
* PurgeLimiter.
|
||||
*
|
||||
* Handles purge limiting, so purging is not triggered too frequently.
|
||||
*/
|
||||
class PurgeLimiter extends AbstractPersistence
|
||||
{
|
||||
/**
|
||||
* time limit in seconds, defaults to 300s
|
||||
* time limit in seconds, defaults to 300s.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @var int
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private static $_limit = 300;
|
||||
|
||||
/**
|
||||
* set the time limit in seconds
|
||||
* set the time limit in seconds.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param int $limit
|
||||
*
|
||||
* @param int $limit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setLimit($limit)
|
||||
@ -44,11 +46,12 @@ class PurgeLimiter extends AbstractPersistence
|
||||
}
|
||||
|
||||
/**
|
||||
* set configuration options of the traffic limiter
|
||||
* set configuration options of the traffic limiter.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param Configuration $conf
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setConfiguration(Configuration $conf)
|
||||
@ -58,11 +61,12 @@ class PurgeLimiter extends AbstractPersistence
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the purge can be performed
|
||||
* check if the purge can be performed.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function canPurge()
|
||||
@ -72,9 +76,9 @@ class PurgeLimiter extends AbstractPersistence
|
||||
return true;
|
||||
}
|
||||
|
||||
$file = 'purge_limiter.php';
|
||||
$now = time();
|
||||
$content = '<?php' . PHP_EOL . '$GLOBALS[\'purge_limiter\'] = ' . $now . ';' . PHP_EOL;
|
||||
$file = 'purge_limiter.php';
|
||||
$now = time();
|
||||
$content = '<?php'.PHP_EOL.'$GLOBALS[\'purge_limiter\'] = '.$now.';'.PHP_EOL;
|
||||
if (!self::_exists($file)) {
|
||||
self::_store($file, $content);
|
||||
}
|
||||
@ -89,6 +93,7 @@ class PurgeLimiter extends AbstractPersistence
|
||||
$result = true;
|
||||
self::_store($file, $content);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Persistence;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* ServerSalt
|
||||
* ServerSalt.
|
||||
*
|
||||
* This is a random string which is unique to each PrivateBin installation.
|
||||
* It is automatically created if not present.
|
||||
@ -27,42 +28,44 @@ use Exception;
|
||||
class ServerSalt extends AbstractPersistence
|
||||
{
|
||||
/**
|
||||
* file where salt is saved to
|
||||
* file where salt is saved to.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_file = 'salt.php';
|
||||
|
||||
/**
|
||||
* generated salt
|
||||
* generated salt.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_salt = '';
|
||||
|
||||
/**
|
||||
* generate a large random hexadecimal salt
|
||||
* generate a large random hexadecimal salt.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generate()
|
||||
{
|
||||
$randomSalt = bin2hex(random_bytes(256));
|
||||
|
||||
return $randomSalt;
|
||||
}
|
||||
|
||||
/**
|
||||
* get server salt
|
||||
* get server salt.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get()
|
||||
@ -76,25 +79,27 @@ class ServerSalt extends AbstractPersistence
|
||||
$items = explode('|', file_get_contents(self::getPath(self::$_file)));
|
||||
}
|
||||
if (!isset($items) || !is_array($items) || count($items) != 3) {
|
||||
throw new Exception('unable to read file ' . self::getPath(self::$_file), 20);
|
||||
throw new Exception('unable to read file '.self::getPath(self::$_file), 20);
|
||||
}
|
||||
self::$_salt = $items[1];
|
||||
} else {
|
||||
self::$_salt = self::generate();
|
||||
self::_store(
|
||||
self::$_file,
|
||||
'<?php /* |' . self::$_salt . '| */ ?>'
|
||||
'<?php /* |'.self::$_salt.'| */ ?>'
|
||||
);
|
||||
}
|
||||
|
||||
return self::$_salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the path
|
||||
* set the path.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $path
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setPath($path)
|
||||
|
@ -1,50 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin\Persistence;
|
||||
|
||||
use PrivateBin\Configuration;
|
||||
|
||||
/**
|
||||
* TrafficLimiter
|
||||
* TrafficLimiter.
|
||||
*
|
||||
* Handles traffic limiting, so no user does more than one call per 10 seconds.
|
||||
*/
|
||||
class TrafficLimiter extends AbstractPersistence
|
||||
{
|
||||
/**
|
||||
* time limit in seconds, defaults to 10s
|
||||
* time limit in seconds, defaults to 10s.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @var int
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private static $_limit = 10;
|
||||
|
||||
/**
|
||||
* key to fetch IP address
|
||||
* key to fetch IP address.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @var string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_ipKey = 'REMOTE_ADDR';
|
||||
|
||||
/**
|
||||
* set the time limit in seconds
|
||||
* set the time limit in seconds.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param int $limit
|
||||
*
|
||||
* @param int $limit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setLimit($limit)
|
||||
@ -53,11 +55,12 @@ class TrafficLimiter extends AbstractPersistence
|
||||
}
|
||||
|
||||
/**
|
||||
* set configuration options of the traffic limiter
|
||||
* set configuration options of the traffic limiter.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param Configuration $conf
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setConfiguration(Configuration $conf)
|
||||
@ -65,7 +68,7 @@ class TrafficLimiter extends AbstractPersistence
|
||||
self::setLimit($conf->getKey('limit', 'traffic'));
|
||||
self::setPath($conf->getKey('dir', 'traffic'));
|
||||
if (($option = $conf->getKey('header', 'traffic')) !== null) {
|
||||
$httpHeader = 'HTTP_' . $option;
|
||||
$httpHeader = 'HTTP_'.$option;
|
||||
if (array_key_exists($httpHeader, $_SERVER) && !empty($_SERVER[$httpHeader])) {
|
||||
self::$_ipKey = $httpHeader;
|
||||
}
|
||||
@ -73,11 +76,12 @@ class TrafficLimiter extends AbstractPersistence
|
||||
}
|
||||
|
||||
/**
|
||||
* get a HMAC of the current visitors IP address
|
||||
* get a HMAC of the current visitors IP address.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $algo
|
||||
*
|
||||
* @param string $algo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getHash($algo = 'sha512')
|
||||
@ -86,13 +90,14 @@ class TrafficLimiter extends AbstractPersistence
|
||||
}
|
||||
|
||||
/**
|
||||
* traffic limiter
|
||||
* traffic limiter.
|
||||
*
|
||||
* Make sure the IP address makes at most 1 request every 10 seconds.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function canPass()
|
||||
@ -106,15 +111,15 @@ class TrafficLimiter extends AbstractPersistence
|
||||
if (!self::_exists($file)) {
|
||||
self::_store(
|
||||
$file,
|
||||
'<?php' . PHP_EOL .
|
||||
'$GLOBALS[\'traffic_limiter\'] = array();' . PHP_EOL
|
||||
'<?php'.PHP_EOL.
|
||||
'$GLOBALS[\'traffic_limiter\'] = array();'.PHP_EOL
|
||||
);
|
||||
}
|
||||
|
||||
$path = self::getPath($file);
|
||||
require $path;
|
||||
$now = time();
|
||||
$tl = $GLOBALS['traffic_limiter'];
|
||||
$tl = $GLOBALS['traffic_limiter'];
|
||||
|
||||
// purge file of expired hashes to keep it small
|
||||
foreach ($tl as $key => $time) {
|
||||
@ -129,14 +134,15 @@ class TrafficLimiter extends AbstractPersistence
|
||||
$result = false;
|
||||
} else {
|
||||
$tl[$hash] = time();
|
||||
$result = true;
|
||||
$result = true;
|
||||
}
|
||||
self::_store(
|
||||
$file,
|
||||
'<?php' . PHP_EOL .
|
||||
'$GLOBALS[\'traffic_limiter\'] = ' .
|
||||
var_export($tl, true) . ';' . PHP_EOL
|
||||
'<?php'.PHP_EOL.
|
||||
'$GLOBALS[\'traffic_limiter\'] = '.
|
||||
var_export($tl, true).';'.PHP_EOL
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -1,121 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use Exception;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* Controller, puts it all together.
|
||||
*/
|
||||
class PrivateBin
|
||||
{
|
||||
/**
|
||||
* version
|
||||
* version.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const VERSION = '1.0';
|
||||
|
||||
/**
|
||||
* show the same error message if the paste expired or does not exist
|
||||
* show the same error message if the paste expired or does not exist.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const GENERIC_ERROR = 'Paste does not exist, has expired or has been deleted.';
|
||||
|
||||
/**
|
||||
* configuration
|
||||
* configuration.
|
||||
*
|
||||
* @access private
|
||||
* @var Configuration
|
||||
* @var Configuration
|
||||
*/
|
||||
private $_conf;
|
||||
|
||||
/**
|
||||
* data
|
||||
* data.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
private $_data = '';
|
||||
|
||||
/**
|
||||
* does the paste expire
|
||||
* does the paste expire.
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
* @var bool
|
||||
*/
|
||||
private $_doesExpire = false;
|
||||
|
||||
/**
|
||||
* error message
|
||||
* error message.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
private $_error = '';
|
||||
|
||||
/**
|
||||
* status message
|
||||
* status message.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
private $_status = '';
|
||||
|
||||
/**
|
||||
* JSON message
|
||||
* JSON message.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
private $_json = '';
|
||||
|
||||
/**
|
||||
* Factory of instance models
|
||||
* Factory of instance models.
|
||||
*
|
||||
* @access private
|
||||
* @var model
|
||||
* @var model
|
||||
*/
|
||||
private $_model;
|
||||
|
||||
/**
|
||||
* request
|
||||
* request.
|
||||
*
|
||||
* @access private
|
||||
* @var request
|
||||
* @var request
|
||||
*/
|
||||
private $_request;
|
||||
|
||||
/**
|
||||
* URL base
|
||||
* URL base.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
private $_urlBase;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* constructor.
|
||||
*
|
||||
* initializes and runs PrivateBin
|
||||
*
|
||||
* @access public
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
@ -145,12 +137,13 @@ class PrivateBin
|
||||
break;
|
||||
case 'jsonld':
|
||||
$this->_jsonld($this->_request->getParam('jsonld'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// output JSON or HTML
|
||||
if ($this->_request->isJsonApiCall()) {
|
||||
header('Content-type: ' . Request::MIME_JSON);
|
||||
header('Content-type: '.Request::MIME_JSON);
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
|
||||
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type');
|
||||
@ -161,27 +154,26 @@ class PrivateBin
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize privatebin
|
||||
* initialize privatebin.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function _init()
|
||||
{
|
||||
foreach (array('cfg', 'lib') as $dir) {
|
||||
if (!is_file(PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess')) {
|
||||
foreach (['cfg', 'lib'] as $dir) {
|
||||
if (!is_file(PATH.$dir.DIRECTORY_SEPARATOR.'.htaccess')) {
|
||||
file_put_contents(
|
||||
PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess',
|
||||
'Allow from none' . PHP_EOL .
|
||||
'Deny from all' . PHP_EOL,
|
||||
PATH.$dir.DIRECTORY_SEPARATOR.'.htaccess',
|
||||
'Allow from none'.PHP_EOL.
|
||||
'Deny from all'.PHP_EOL,
|
||||
LOCK_EX
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_conf = new Configuration;
|
||||
$this->_model = new Model($this->_conf);
|
||||
$this->_request = new Request;
|
||||
$this->_conf = new Configuration();
|
||||
$this->_model = new Model($this->_conf);
|
||||
$this->_request = new Request();
|
||||
$this->_urlBase = array_key_exists('REQUEST_URI', $_SERVER) ?
|
||||
htmlspecialchars($_SERVER['REQUEST_URI']) : '/';
|
||||
ServerSalt::setPath($this->_conf->getKey('dir', 'traffic'));
|
||||
@ -197,7 +189,7 @@ class PrivateBin
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new paste or comment
|
||||
* Store new paste or comment.
|
||||
*
|
||||
* POST contains one or both:
|
||||
* data = json encoded SJCL encrypted text (containing keys: iv,v,iter,ks,ts,mode,adata,cipher,salt,ct)
|
||||
@ -213,7 +205,6 @@ class PrivateBin
|
||||
* parentid (optional) = in discussion, which comment this comment replies to.
|
||||
* pasteid (optional) = in discussion, which paste this comment belongs to.
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function _create()
|
||||
@ -229,8 +220,8 @@ class PrivateBin
|
||||
);
|
||||
}
|
||||
|
||||
$data = $this->_request->getParam('data');
|
||||
$attachment = $this->_request->getParam('attachment');
|
||||
$data = $this->_request->getParam('data');
|
||||
$attachment = $this->_request->getParam('attachment');
|
||||
$attachmentname = $this->_request->getParam('attachmentname');
|
||||
|
||||
// Ensure content is not too big.
|
||||
@ -253,7 +244,7 @@ class PrivateBin
|
||||
}
|
||||
|
||||
// The user posts a comment.
|
||||
$pasteid = $this->_request->getParam('pasteid');
|
||||
$pasteid = $this->_request->getParam('pasteid');
|
||||
$parentid = $this->_request->getParam('parentid');
|
||||
if (!empty($pasteid) && !empty($parentid)) {
|
||||
$paste = $this->_model->getPaste($pasteid);
|
||||
@ -314,16 +305,16 @@ class PrivateBin
|
||||
} catch (Exception $e) {
|
||||
return $this->_return_message(1, $e->getMessage());
|
||||
}
|
||||
$this->_return_message(0, $paste->getId(), array('deletetoken' => $paste->getDeleteToken()));
|
||||
$this->_return_message(0, $paste->getId(), ['deletetoken' => $paste->getDeleteToken()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an existing paste
|
||||
* Delete an existing paste.
|
||||
*
|
||||
* @param string $dataid
|
||||
* @param string $deletetoken
|
||||
*
|
||||
* @access private
|
||||
* @param string $dataid
|
||||
* @param string $deletetoken
|
||||
* @return void
|
||||
*/
|
||||
private function _delete($dataid, $deletetoken)
|
||||
@ -360,10 +351,10 @@ class PrivateBin
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an existing paste or comment
|
||||
* Read an existing paste or comment.
|
||||
*
|
||||
* @param string $dataid
|
||||
*
|
||||
* @access private
|
||||
* @param string $dataid
|
||||
* @return void
|
||||
*/
|
||||
private function _read($dataid)
|
||||
@ -371,7 +362,7 @@ class PrivateBin
|
||||
try {
|
||||
$paste = $this->_model->getPaste($dataid);
|
||||
if ($paste->exists()) {
|
||||
$data = $paste->get();
|
||||
$data = $paste->get();
|
||||
$this->_doesExpire = property_exists($data, 'meta') && property_exists($data->meta, 'expire_date');
|
||||
if (property_exists($data->meta, 'salt')) {
|
||||
unset($data->meta->salt);
|
||||
@ -396,7 +387,6 @@ class PrivateBin
|
||||
/**
|
||||
* Display PrivateBin frontend.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function _view()
|
||||
@ -405,16 +395,16 @@ class PrivateBin
|
||||
$time = gmdate('D, d M Y H:i:s \G\M\T');
|
||||
header('Cache-Control: no-store, no-cache, no-transform, must-revalidate');
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: ' . $time);
|
||||
header('Last-Modified: ' . $time);
|
||||
header('Expires: '.$time);
|
||||
header('Last-Modified: '.$time);
|
||||
header('Vary: Accept');
|
||||
header('Content-Security-Policy: ' . $this->_conf->getKey('cspheader'));
|
||||
header('Content-Security-Policy: '.$this->_conf->getKey('cspheader'));
|
||||
header('X-Xss-Protection: 1; mode=block');
|
||||
header('X-Frame-Options: DENY');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
// label all the expiration options
|
||||
$expire = array();
|
||||
$expire = [];
|
||||
foreach ($this->_conf->getSection('expire_options') as $time => $seconds) {
|
||||
$expire[$time] = ($seconds == 0) ? I18n::_(ucfirst($time)) : Filter::formatHumanReadableTime($time);
|
||||
}
|
||||
@ -429,7 +419,7 @@ class PrivateBin
|
||||
setcookie('lang', $languageselection);
|
||||
}
|
||||
|
||||
$page = new View;
|
||||
$page = new View();
|
||||
$page->assign('CIPHERDATA', $this->_data);
|
||||
$page->assign('ERROR', I18n::_($this->_error));
|
||||
$page->assign('STATUS', I18n::_($this->_status));
|
||||
@ -456,10 +446,10 @@ class PrivateBin
|
||||
}
|
||||
|
||||
/**
|
||||
* outputs requested JSON-LD context
|
||||
* outputs requested JSON-LD context.
|
||||
*
|
||||
* @access private
|
||||
* @param string $type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _jsonld($type)
|
||||
@ -471,11 +461,11 @@ class PrivateBin
|
||||
$type = '';
|
||||
}
|
||||
$content = '{}';
|
||||
$file = PUBLIC_PATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . $type . '.jsonld';
|
||||
$file = PUBLIC_PATH.DIRECTORY_SEPARATOR.'js'.DIRECTORY_SEPARATOR.$type.'.jsonld';
|
||||
if (is_readable($file)) {
|
||||
$content = str_replace(
|
||||
'?jsonld=',
|
||||
$this->_urlBase . '?jsonld=',
|
||||
$this->_urlBase.'?jsonld=',
|
||||
file_get_contents($file)
|
||||
);
|
||||
}
|
||||
@ -487,22 +477,22 @@ class PrivateBin
|
||||
}
|
||||
|
||||
/**
|
||||
* prepares JSON encoded status message
|
||||
* prepares JSON encoded status message.
|
||||
*
|
||||
* @param int $status
|
||||
* @param string $message
|
||||
* @param array $other
|
||||
*
|
||||
* @access private
|
||||
* @param int $status
|
||||
* @param string $message
|
||||
* @param array $other
|
||||
* @return void
|
||||
*/
|
||||
private function _return_message($status, $message, $other = array())
|
||||
private function _return_message($status, $message, $other = [])
|
||||
{
|
||||
$result = array('status' => $status);
|
||||
$result = ['status' => $status];
|
||||
if ($status) {
|
||||
$result['message'] = I18n::_($message);
|
||||
} else {
|
||||
$result['id'] = $message;
|
||||
$result['url'] = $this->_urlBase . '?' . $message;
|
||||
$result['id'] = $message;
|
||||
$result['url'] = $this->_urlBase.'?'.$message;
|
||||
}
|
||||
$result += $other;
|
||||
$this->_json = json_encode($result);
|
||||
|
@ -1,40 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
/**
|
||||
* Request
|
||||
* Request.
|
||||
*
|
||||
* parses request parameters and provides helper functions for routing
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* MIME type for JSON
|
||||
* MIME type for JSON.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const MIME_JSON = 'application/json';
|
||||
|
||||
/**
|
||||
* MIME type for HTML
|
||||
* MIME type for HTML.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
const MIME_HTML = 'text/html';
|
||||
|
||||
/**
|
||||
* MIME type for XHTML
|
||||
* MIME type for XHTML.
|
||||
*
|
||||
* @const string
|
||||
*/
|
||||
@ -43,7 +44,6 @@ class Request
|
||||
/**
|
||||
* Input stream to use for PUT parameter parsing.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private static $_inputStream = 'php://input';
|
||||
@ -51,7 +51,6 @@ class Request
|
||||
/**
|
||||
* Operation to perform.
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $_operation = 'view';
|
||||
@ -59,15 +58,13 @@ class Request
|
||||
/**
|
||||
* Request parameters.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $_params = array();
|
||||
private $_params = [];
|
||||
|
||||
/**
|
||||
* If we are in a JSON API context.
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
private $_isJsonApi = false;
|
||||
@ -75,15 +72,14 @@ class Request
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// in case stupid admin has left magic_quotes enabled in php.ini (for PHP < 5.4)
|
||||
if (version_compare(PHP_VERSION, '5.4.0') < 0 && get_magic_quotes_gpc()) {
|
||||
$_POST = array_map('PrivateBin\\Filter::stripslashesDeep', $_POST);
|
||||
$_GET = array_map('PrivateBin\\Filter::stripslashesDeep', $_GET);
|
||||
$_POST = array_map('PrivateBin\\Filter::stripslashesDeep', $_POST);
|
||||
$_GET = array_map('PrivateBin\\Filter::stripslashesDeep', $_GET);
|
||||
$_COOKIE = array_map('PrivateBin\\Filter::stripslashesDeep', $_COOKIE);
|
||||
}
|
||||
|
||||
@ -131,7 +127,6 @@ class Request
|
||||
/**
|
||||
* Get current operation.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getOperation()
|
||||
@ -142,9 +137,9 @@ class Request
|
||||
/**
|
||||
* Get a request parameter.
|
||||
*
|
||||
* @access public
|
||||
* @param string $param
|
||||
* @param string $default
|
||||
* @param string $param
|
||||
* @param string $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getParam($param, $default = '')
|
||||
@ -155,7 +150,6 @@ class Request
|
||||
/**
|
||||
* If we are in a JSON API context.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function isJsonApiCall()
|
||||
@ -174,17 +168,16 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* detect the clients supported media type and decide if its a JSON API call or not
|
||||
* detect the clients supported media type and decide if its a JSON API call or not.
|
||||
*
|
||||
* Adapted from: https://stackoverflow.com/questions/3770513/detect-browser-language-in-php#3771447
|
||||
*
|
||||
* @access private
|
||||
* @return bool
|
||||
*/
|
||||
private function _detectJsonRequest()
|
||||
{
|
||||
$hasAcceptHeader = array_key_exists('HTTP_ACCEPT', $_SERVER);
|
||||
$acceptHeader = $hasAcceptHeader ? $_SERVER['HTTP_ACCEPT'] : '';
|
||||
$acceptHeader = $hasAcceptHeader ? $_SERVER['HTTP_ACCEPT'] : '';
|
||||
|
||||
// simple cases
|
||||
if (
|
||||
@ -199,7 +192,7 @@ class Request
|
||||
}
|
||||
|
||||
// advanced case: media type negotiation
|
||||
$mediaTypes = array();
|
||||
$mediaTypes = [];
|
||||
if ($hasAcceptHeader) {
|
||||
$mediaTypeRanges = explode(',', trim($acceptHeader));
|
||||
foreach ($mediaTypeRanges as $mediaTypeRange) {
|
||||
@ -213,7 +206,7 @@ class Request
|
||||
$match[2] = (string) floatval($match[2]);
|
||||
}
|
||||
if (!isset($mediaTypes[$match[2]])) {
|
||||
$mediaTypes[$match[2]] = array();
|
||||
$mediaTypes[$match[2]] = [];
|
||||
}
|
||||
$mediaTypes[$match[2]][] = strtolower($match[1]);
|
||||
}
|
||||
@ -235,6 +228,7 @@ class Request
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
22
lib/Sjcl.php
22
lib/Sjcl.php
@ -1,37 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
/**
|
||||
* Sjcl
|
||||
* Sjcl.
|
||||
*
|
||||
* Provides SJCL validation function.
|
||||
*/
|
||||
class Sjcl
|
||||
{
|
||||
/**
|
||||
* SJCL validator
|
||||
* SJCL validator.
|
||||
*
|
||||
* Checks if a json string is a proper SJCL encrypted message.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $encoded JSON
|
||||
*
|
||||
* @param string $encoded JSON
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValid($encoded)
|
||||
{
|
||||
$accepted_keys = array('iv','v','iter','ks','ts','mode','adata','cipher','salt','ct');
|
||||
$accepted_keys = ['iv', 'v', 'iter', 'ks', 'ts', 'mode', 'adata', 'cipher', 'salt', 'ct'];
|
||||
|
||||
// Make sure content is valid json
|
||||
$decoded = json_decode($encoded);
|
||||
@ -80,13 +82,13 @@ class Sjcl
|
||||
if (!is_int($decoded['iter']) || $decoded['iter'] <= 100) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($decoded['ks'], array(128, 192, 256), true)) {
|
||||
if (!in_array($decoded['ks'], [128, 192, 256], true)) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($decoded['ts'], array(64, 96, 128), true)) {
|
||||
if (!in_array($decoded['ts'], [64, 96, 128], true)) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($decoded['mode'], array('ccm', 'ocb2', 'gcm'), true)) {
|
||||
if (!in_array($decoded['mode'], ['ccm', 'ocb2', 'gcm'], true)) {
|
||||
return false;
|
||||
}
|
||||
if ($decoded['cipher'] !== 'aes') {
|
||||
|
33
lib/View.php
33
lib/View.php
@ -1,40 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* PrivateBin
|
||||
* PrivateBin.
|
||||
*
|
||||
* a zero-knowledge paste bin
|
||||
*
|
||||
* @link https://github.com/PrivateBin/PrivateBin
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* View
|
||||
* View.
|
||||
*
|
||||
* Displays the templates
|
||||
*/
|
||||
class View
|
||||
{
|
||||
/**
|
||||
* variables available in the template
|
||||
* variables available in the template.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
* @var array
|
||||
*/
|
||||
private $_variables = array();
|
||||
private $_variables = [];
|
||||
|
||||
/**
|
||||
* assign variables to be used inside of the template
|
||||
* assign variables to be used inside of the template.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @access public
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function assign($name, $value)
|
||||
@ -43,18 +43,19 @@ class View
|
||||
}
|
||||
|
||||
/**
|
||||
* render a template
|
||||
* render a template.
|
||||
*
|
||||
* @param string $template
|
||||
*
|
||||
* @access public
|
||||
* @param string $template
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function draw($template)
|
||||
{
|
||||
$path = PATH . 'tpl' . DIRECTORY_SEPARATOR . $template . '.php';
|
||||
$path = PATH.'tpl'.DIRECTORY_SEPARATOR.$template.'.php';
|
||||
if (!file_exists($path)) {
|
||||
throw new Exception('Template ' . $template . ' not found!', 80);
|
||||
throw new Exception('Template '.$template.' not found!', 80);
|
||||
}
|
||||
extract($this->_variables);
|
||||
include $path;
|
||||
|
@ -1,20 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* VizHash_GD
|
||||
* VizHash_GD.
|
||||
*
|
||||
* Visual Hash implementation in php4+GD,
|
||||
* stripped down and modified version for PrivateBin
|
||||
*
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
|
||||
*
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
*
|
||||
* @version 0.0.5 beta PrivateBin 1.0
|
||||
*/
|
||||
|
||||
namespace PrivateBin;
|
||||
|
||||
/**
|
||||
* Vizhash16x16
|
||||
* Vizhash16x16.
|
||||
*
|
||||
* Example:
|
||||
* $vz = new Vizhash16x16();
|
||||
@ -23,50 +24,44 @@ namespace PrivateBin;
|
||||
* echo $data;
|
||||
* exit;
|
||||
*/
|
||||
|
||||
class Vizhash16x16
|
||||
{
|
||||
/**
|
||||
* hash values
|
||||
* hash values.
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
* @var array
|
||||
*/
|
||||
private $VALUES;
|
||||
|
||||
/**
|
||||
* index of current value
|
||||
* index of current value.
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
* @var int
|
||||
*/
|
||||
private $VALUES_INDEX;
|
||||
|
||||
/**
|
||||
* image width
|
||||
* image width.
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
* @var int
|
||||
*/
|
||||
private $width;
|
||||
|
||||
/**
|
||||
* image height
|
||||
* image height.
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
* @var int
|
||||
*/
|
||||
private $height;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* constructor.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->width = 16;
|
||||
$this->width = 16;
|
||||
$this->height = 16;
|
||||
}
|
||||
|
||||
@ -75,8 +70,8 @@ class Vizhash16x16
|
||||
*
|
||||
* The given text should to be 128 to 150 characters long
|
||||
*
|
||||
* @access public
|
||||
* @param string $text
|
||||
* @param string $text
|
||||
*
|
||||
* @return string PNG data. Or empty string if GD is not available.
|
||||
*/
|
||||
public function generate($text)
|
||||
@ -88,7 +83,7 @@ class Vizhash16x16
|
||||
$textlen = strlen($text);
|
||||
|
||||
// We convert the hash into an array of integers.
|
||||
$this->VALUES = array();
|
||||
$this->VALUES = [];
|
||||
for ($i = 0; $i < $textlen; $i = $i + 2) {
|
||||
array_push($this->VALUES, hexdec(substr($text, $i, 2)));
|
||||
}
|
||||
@ -105,15 +100,15 @@ class Vizhash16x16
|
||||
$op = 'v';
|
||||
if (($this->getInt() % 2) == 0) {
|
||||
$op = 'h';
|
||||
};
|
||||
$image = $this->degrade($image, $op, array($r0, $g0, $b0), array(0, 0, 0));
|
||||
}
|
||||
$image = $this->degrade($image, $op, [$r0, $g0, $b0], [0, 0, 0]);
|
||||
|
||||
for ($i = 0; $i < 7; ++$i) {
|
||||
$action = $this->getInt();
|
||||
$color = imagecolorallocate($image, $r, $g, $b);
|
||||
$r = $r0 = ($r0 + $this->getInt() / 25) % 256;
|
||||
$g = $g0 = ($g0 + $this->getInt() / 25) % 256;
|
||||
$b = $b0 = ($b0 + $this->getInt() / 25) % 256;
|
||||
$color = imagecolorallocate($image, $r, $g, $b);
|
||||
$r = $r0 = ($r0 + $this->getInt() / 25) % 256;
|
||||
$g = $g0 = ($g0 + $this->getInt() / 25) % 256;
|
||||
$b = $b0 = ($b0 + $this->getInt() / 25) % 256;
|
||||
$this->drawshape($image, $action, $color);
|
||||
}
|
||||
|
||||
@ -129,9 +124,8 @@ class Vizhash16x16
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single integer from the $VALUES array (0...255)
|
||||
* Returns a single integer from the $VALUES array (0...255).
|
||||
*
|
||||
* @access private
|
||||
* @return int
|
||||
*/
|
||||
private function getInt()
|
||||
@ -143,9 +137,8 @@ class Vizhash16x16
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single integer from the array (roughly mapped to image width)
|
||||
* Returns a single integer from the array (roughly mapped to image width).
|
||||
*
|
||||
* @access private
|
||||
* @return int
|
||||
*/
|
||||
private function getX()
|
||||
@ -154,9 +147,8 @@ class Vizhash16x16
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single integer from the array (roughly mapped to image height)
|
||||
* Returns a single integer from the array (roughly mapped to image height).
|
||||
*
|
||||
* @access private
|
||||
* @return int
|
||||
*/
|
||||
private function getY()
|
||||
@ -165,32 +157,32 @@ class Vizhash16x16
|
||||
}
|
||||
|
||||
/**
|
||||
* Gradient function
|
||||
* Gradient function.
|
||||
*
|
||||
* taken from:
|
||||
* http://www.supportduweb.com/scripts_tutoriaux-code-source-41-gd-faire-un-degrade-en-php-gd-fonction-degrade-imagerie.html
|
||||
*
|
||||
* @access private
|
||||
* @param resource $img
|
||||
* @param string $direction
|
||||
* @param array $color1
|
||||
* @param array $color2
|
||||
* @param resource $img
|
||||
* @param string $direction
|
||||
* @param array $color1
|
||||
* @param array $color2
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private function degrade($img, $direction, $color1, $color2)
|
||||
{
|
||||
if ($direction == 'h') {
|
||||
$size = imagesx($img);
|
||||
$size = imagesx($img);
|
||||
$sizeinv = imagesy($img);
|
||||
} else {
|
||||
$size = imagesy($img);
|
||||
$size = imagesy($img);
|
||||
$sizeinv = imagesx($img);
|
||||
}
|
||||
$diffs = array(
|
||||
$diffs = [
|
||||
(($color2[0] - $color1[0]) / $size),
|
||||
(($color2[1] - $color1[1]) / $size),
|
||||
(($color2[2] - $color1[2]) / $size)
|
||||
);
|
||||
(($color2[2] - $color1[2]) / $size),
|
||||
];
|
||||
for ($i = 0; $i < $size; ++$i) {
|
||||
$r = $color1[0] + ($diffs[0] * $i);
|
||||
$g = $color1[1] + ($diffs[1] * $i);
|
||||
@ -201,36 +193,37 @@ class Vizhash16x16
|
||||
imageline($img, 0, $i, $sizeinv, $i, imagecolorallocate($img, $r, $g, $b));
|
||||
}
|
||||
}
|
||||
|
||||
return $img;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a shape
|
||||
* Draw a shape.
|
||||
*
|
||||
* @param resource $image
|
||||
* @param int $action
|
||||
* @param int $color
|
||||
*
|
||||
* @access private
|
||||
* @param resource $image
|
||||
* @param int $action
|
||||
* @param int $color
|
||||
* @return void
|
||||
*/
|
||||
private function drawshape($image, $action, $color)
|
||||
{
|
||||
switch ($action % 7) {
|
||||
case 0:
|
||||
ImageFilledRectangle($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
|
||||
imagefilledrectangle($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
ImageFilledEllipse($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
|
||||
imagefilledellipse($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $color);
|
||||
break;
|
||||
case 3:
|
||||
$points = array($this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY());
|
||||
ImageFilledPolygon($image, $points, 4, $color);
|
||||
$points = [$this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY(), $this->getX(), $this->getY()];
|
||||
imagefilledpolygon($image, $points, 4, $color);
|
||||
break;
|
||||
default:
|
||||
$start = $this->getInt() * 360 / 256;
|
||||
$end = $start + $this->getInt() * 180 / 256;
|
||||
ImageFilledArc($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $start, $end, $color, IMG_ARC_PIE);
|
||||
$end = $start + $this->getInt() * 180 / 256;
|
||||
imagefilledarc($image, $this->getX(), $this->getY(), $this->getX(), $this->getY(), $start, $end, $color, IMG_ARC_PIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use PrivateBin\I18n;
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use PrivateBin\I18n;
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use PrivateBin\I18n;
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use PrivateBin\I18n;
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use PrivateBin\I18n;
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use PrivateBin\I18n;
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -9,73 +9,73 @@ if (!defined('PUBLIC_PATH')) {
|
||||
define('PUBLIC_PATH', '..');
|
||||
}
|
||||
if (!defined('PATH')) {
|
||||
define('PATH', '..' . DIRECTORY_SEPARATOR);
|
||||
define('PATH', '..'.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
if (!defined('CONF')) {
|
||||
define('CONF', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.ini');
|
||||
define('CONF', PATH.'cfg'.DIRECTORY_SEPARATOR.'conf.ini');
|
||||
}
|
||||
if (!is_file(CONF)) {
|
||||
copy(CONF . '.sample', CONF);
|
||||
copy(CONF.'.sample', CONF);
|
||||
}
|
||||
|
||||
require PATH . 'vendor/autoload.php';
|
||||
require PATH.'vendor/autoload.php';
|
||||
Helper::updateSubresourceIntegrity();
|
||||
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
* example ID of a paste
|
||||
* example ID of a paste.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $pasteid = '5e9bc25c89fb3bf9';
|
||||
|
||||
/**
|
||||
* example paste
|
||||
* example paste.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $paste = array(
|
||||
'data' => '{"iv":"EN39/wd5Nk8HAiSG2K5AsQ","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QKN1DBXe5PI","ct":"8hA83xDdXjD7K2qfmw5NdA"}',
|
||||
'attachment' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
|
||||
private static $paste = [
|
||||
'data' => '{"iv":"EN39/wd5Nk8HAiSG2K5AsQ","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QKN1DBXe5PI","ct":"8hA83xDdXjD7K2qfmw5NdA"}',
|
||||
'attachment' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
|
||||
'attachmentname' => '{"iv":"76MkAtOGC4oFogX/aSMxRA","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"b6Ae/U1xJdsX/+lATud4sQ"}',
|
||||
'meta' => array(
|
||||
'formatter' => 'plaintext',
|
||||
'postdate' => 1344803344,
|
||||
'meta' => [
|
||||
'formatter' => 'plaintext',
|
||||
'postdate' => 1344803344,
|
||||
'opendiscussion' => true,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* example ID of a comment
|
||||
* example ID of a comment.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $commentid = '5a52eebf11c4c94b';
|
||||
|
||||
/**
|
||||
* example comment
|
||||
* example comment.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $comment = array(
|
||||
private static $comment = [
|
||||
'data' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
|
||||
'meta' => array(
|
||||
'meta' => [
|
||||
'nickname' => '{"iv":"76MkAtOGC4oFogX/aSMxRA","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"b6Ae/U1xJdsX/+lATud4sQ"}',
|
||||
'vizhash' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGUlEQVQokWOsl5/94983CNKQMjnxaOePf98MeKwPfNjkLZ3AgARab6b9+PeNEVnDj3/ff/z7ZiHnzsDA8Pv7H2TVPJw8EAYLAwb48OaVgIgYKycLsrYv378wMDB8//qdCVMDRA9EKSsnCwRBxNsepaLboMFlyMDAICAi9uHNK24GITQ/MDAwoNhgIGMLtwGrzegaLjw5jMz9+vUdnN17uwDCQDhJgk0O07yvX9+teDX1x79v6DYIsIjgcgMaYGFgYOBg4kJx2JejkAiBxAw+PzAwMNz4dp6wDXDw4MdNNOl0rWYsNkD89OLXI/xmo9sgzatJjAYmBgYGDiauD3/ePP18nVgb4MF89+M5ZX6js293wUMpnr8KTQMAxsCJnJ30apMAAAAASUVORK5CYII=',
|
||||
'vizhash' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGUlEQVQokWOsl5/94983CNKQMjnxaOePf98MeKwPfNjkLZ3AgARab6b9+PeNEVnDj3/ff/z7ZiHnzsDA8Pv7H2TVPJw8EAYLAwb48OaVgIgYKycLsrYv378wMDB8//qdCVMDRA9EKSsnCwRBxNsepaLboMFlyMDAICAi9uHNK24GITQ/MDAwoNhgIGMLtwGrzegaLjw5jMz9+vUdnN17uwDCQDhJgk0O07yvX9+teDX1x79v6DYIsIjgcgMaYGFgYOBg4kJx2JejkAiBxAw+PzAwMNz4dp6wDXDw4MdNNOl0rWYsNkD89OLXI/xmo9sgzatJjAYmBgYGDiauD3/ePP18nVgb4MF89+M5ZX6js293wUMpnr8KTQMAxsCJnJ30apMAAAAASUVORK5CYII=',
|
||||
'postdate' => 1344803528,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* JS files and their SRI hashes
|
||||
* JS files and their SRI hashes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $hashes = array();
|
||||
private static $hashes = [];
|
||||
|
||||
/**
|
||||
* get example paste ID
|
||||
* get example paste ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -85,36 +85,38 @@ class Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* get example paste
|
||||
* get example paste.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPaste($meta = array())
|
||||
public static function getPaste($meta = [])
|
||||
{
|
||||
$example = self::getPasteWithAttachment($meta);
|
||||
unset($example['attachment'], $example['attachmentname']);
|
||||
|
||||
return $example;
|
||||
}
|
||||
|
||||
/**
|
||||
* get example paste
|
||||
* get example paste.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPasteWithAttachment($meta = array())
|
||||
public static function getPasteWithAttachment($meta = [])
|
||||
{
|
||||
$example = self::$paste;
|
||||
$example['meta']['salt'] = ServerSalt::generate();
|
||||
$example['meta'] = array_merge($example['meta'], $meta);
|
||||
|
||||
return $example;
|
||||
}
|
||||
|
||||
/**
|
||||
* get example paste
|
||||
* get example paste.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPasteAsJson($meta = array())
|
||||
public static function getPasteAsJson($meta = [])
|
||||
{
|
||||
$example = self::getPaste();
|
||||
// the JSON shouldn't contain the salt
|
||||
@ -122,15 +124,16 @@ class Helper
|
||||
if (count($meta)) {
|
||||
$example['meta'] = $meta;
|
||||
}
|
||||
$example['comments'] = array();
|
||||
$example['comments'] = [];
|
||||
$example['comment_count'] = 0;
|
||||
$example['comment_offset'] = 0;
|
||||
$example['@context'] = 'js/paste.jsonld';
|
||||
|
||||
return json_encode($example);
|
||||
}
|
||||
|
||||
/**
|
||||
* get example paste ID
|
||||
* get example paste ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -140,34 +143,37 @@ class Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* get example comment
|
||||
* get example comment.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getComment($meta = array())
|
||||
public static function getComment($meta = [])
|
||||
{
|
||||
$example = self::$comment;
|
||||
$example['meta'] = array_merge($example['meta'], $meta);
|
||||
|
||||
return $example;
|
||||
}
|
||||
|
||||
/**
|
||||
* get example comment
|
||||
* get example comment.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCommentPost($meta = array())
|
||||
public static function getCommentPost($meta = [])
|
||||
{
|
||||
$example = self::getComment($meta);
|
||||
$example['nickname'] = $example['meta']['nickname'];
|
||||
unset($example['meta']['nickname']);
|
||||
|
||||
return $example;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete directory and all its contents recursively
|
||||
* delete directory and all its contents recursively.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function rmDir($path)
|
||||
@ -176,50 +182,50 @@ class Helper
|
||||
$dir = dir($path);
|
||||
while (false !== ($file = $dir->read())) {
|
||||
if ($file != '.' && $file != '..') {
|
||||
if (is_dir($path . $file)) {
|
||||
self::rmDir($path . $file);
|
||||
} elseif (is_file($path . $file)) {
|
||||
if (!unlink($path . $file)) {
|
||||
throw new Exception('Error deleting file "' . $path . $file . '".');
|
||||
if (is_dir($path.$file)) {
|
||||
self::rmDir($path.$file);
|
||||
} elseif (is_file($path.$file)) {
|
||||
if (!unlink($path.$file)) {
|
||||
throw new Exception('Error deleting file "'.$path.$file.'".');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
if (!rmdir($path)) {
|
||||
throw new Exception('Error deleting directory "' . $path . '".');
|
||||
throw new Exception('Error deleting directory "'.$path.'".');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a backup of the config file
|
||||
* create a backup of the config file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function confBackup()
|
||||
{
|
||||
if (!is_file(CONF . '.bak') && is_file(CONF)) {
|
||||
rename(CONF, CONF . '.bak');
|
||||
if (!is_file(CONF.'.bak') && is_file(CONF)) {
|
||||
rename(CONF, CONF.'.bak');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* restor backup of the config file
|
||||
* restor backup of the config file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function confRestore()
|
||||
{
|
||||
if (is_file(CONF . '.bak')) {
|
||||
rename(CONF . '.bak', CONF);
|
||||
if (is_file(CONF.'.bak')) {
|
||||
rename(CONF.'.bak', CONF);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create ini file
|
||||
* create ini file.
|
||||
*
|
||||
* @param string $pathToFile
|
||||
* @param array $values
|
||||
* @param array $values
|
||||
*/
|
||||
public static function createIniFile($pathToFile, $values)
|
||||
{
|
||||
@ -227,28 +233,28 @@ class Helper
|
||||
@unlink($pathToFile);
|
||||
$ini = fopen($pathToFile, 'a');
|
||||
foreach ($values as $section => $options) {
|
||||
fwrite($ini, "[$section]" . PHP_EOL);
|
||||
fwrite($ini, "[$section]".PHP_EOL);
|
||||
foreach ($options as $option => $setting) {
|
||||
if (is_null($setting)) {
|
||||
continue;
|
||||
} elseif (is_string($setting)) {
|
||||
$setting = '"' . $setting . '"';
|
||||
$setting = '"'.$setting.'"';
|
||||
} elseif (is_array($setting)) {
|
||||
foreach ($setting as $key => $value) {
|
||||
if (is_null($value)) {
|
||||
$value = 'null';
|
||||
} elseif (is_string($value)) {
|
||||
$value = '"' . $value . '"';
|
||||
$value = '"'.$value.'"';
|
||||
} else {
|
||||
$value = var_export($value, true);
|
||||
}
|
||||
fwrite($ini, $option . "[$key] = $value" . PHP_EOL);
|
||||
fwrite($ini, $option."[$key] = $value".PHP_EOL);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
$setting = var_export($setting, true);
|
||||
}
|
||||
fwrite($ini, "$option = $setting" . PHP_EOL);
|
||||
fwrite($ini, "$option = $setting".PHP_EOL);
|
||||
}
|
||||
fwrite($ini, PHP_EOL);
|
||||
}
|
||||
@ -258,20 +264,21 @@ class Helper
|
||||
|
||||
/**
|
||||
* a var_export that returns arrays without line breaks
|
||||
* by linus@flowingcreativity.net via php.net
|
||||
* by linus@flowingcreativity.net via php.net.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @param bool $return
|
||||
* @param bool $return
|
||||
*
|
||||
* @return void|string
|
||||
*/
|
||||
public static function varExportMin($var, $return = false)
|
||||
{
|
||||
if (is_array($var)) {
|
||||
$toImplode = array();
|
||||
$toImplode = [];
|
||||
foreach ($var as $key => $value) {
|
||||
$toImplode[] = var_export($key, true) . ' => ' . self::varExportMin($value, true);
|
||||
$toImplode[] = var_export($key, true).' => '.self::varExportMin($value, true);
|
||||
}
|
||||
$code = 'array(' . implode(', ', $toImplode) . ')';
|
||||
$code = 'array('.implode(', ', $toImplode).')';
|
||||
if ($return) {
|
||||
return $code;
|
||||
} else {
|
||||
@ -283,36 +290,36 @@ class Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* update all templates with the latest SRI hashes for all JS files
|
||||
* update all templates with the latest SRI hashes for all JS files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function updateSubresourceIntegrity()
|
||||
{
|
||||
$dir = dir(PATH . 'js');
|
||||
$dir = dir(PATH.'js');
|
||||
while (false !== ($file = $dir->read())) {
|
||||
if (substr($file, -3) === '.js') {
|
||||
self::$hashes[$file] = base64_encode(
|
||||
hash('sha512', file_get_contents(
|
||||
PATH . 'js' . DIRECTORY_SEPARATOR . $file
|
||||
PATH.'js'.DIRECTORY_SEPARATOR.$file
|
||||
), true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$dir = dir(PATH . 'tpl');
|
||||
$dir = dir(PATH.'tpl');
|
||||
while (false !== ($file = $dir->read())) {
|
||||
if (substr($file, -4) === '.php') {
|
||||
$content = file_get_contents(
|
||||
PATH . 'tpl' . DIRECTORY_SEPARATOR . $file
|
||||
PATH.'tpl'.DIRECTORY_SEPARATOR.$file
|
||||
);
|
||||
$content = preg_replace_callback(
|
||||
'#<script type="text/javascript" src="js/([a-z0-9.-]+.js)([^"]*)"( integrity="[^"]+" crossorigin="[^"]+")?></script>#',
|
||||
function ($matches) {
|
||||
if (array_key_exists($matches[1], Helper::$hashes)) {
|
||||
return '<script type="text/javascript" src="js/' .
|
||||
$matches[1] . $matches[2] .
|
||||
'" integrity="sha512-' . Helper::$hashes[$matches[1]] .
|
||||
return '<script type="text/javascript" src="js/'.
|
||||
$matches[1].$matches[2].
|
||||
'" integrity="sha512-'.Helper::$hashes[$matches[1]].
|
||||
'" crossorigin="anonymous"></script>';
|
||||
} else {
|
||||
return $matches[0];
|
||||
@ -321,7 +328,7 @@ class Helper
|
||||
$content
|
||||
);
|
||||
file_put_contents(
|
||||
PATH . 'tpl' . DIRECTORY_SEPARATOR . $file,
|
||||
PATH.'tpl'.DIRECTORY_SEPARATOR.$file,
|
||||
$content
|
||||
);
|
||||
}
|
||||
|
@ -13,10 +13,10 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
/* Setup Routine */
|
||||
Helper::confBackup();
|
||||
$this->_options = configuration::getDefaults();
|
||||
$this->_options['model_options']['dir'] = PATH . $this->_options['model_options']['dir'];
|
||||
$this->_options['traffic']['dir'] = PATH . $this->_options['traffic']['dir'];
|
||||
$this->_options['purge']['dir'] = PATH . $this->_options['purge']['dir'];
|
||||
$this->_minimalConfig = '[main]' . PHP_EOL . '[model]' . PHP_EOL . '[model_options]';
|
||||
$this->_options['model_options']['dir'] = PATH.$this->_options['model_options']['dir'];
|
||||
$this->_options['traffic']['dir'] = PATH.$this->_options['traffic']['dir'];
|
||||
$this->_options['purge']['dir'] = PATH.$this->_options['purge']['dir'];
|
||||
$this->_minimalConfig = '[main]'.PHP_EOL.'[model]'.PHP_EOL.'[model_options]';
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
@ -27,22 +27,22 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testDefaultConfigFile()
|
||||
{
|
||||
$this->assertTrue(copy(CONF . '.bak', CONF), 'copy default configuration file');
|
||||
$conf = new Configuration;
|
||||
$this->assertTrue(copy(CONF.'.bak', CONF), 'copy default configuration file');
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals($this->_options, $conf->get(), 'default configuration is correct');
|
||||
}
|
||||
|
||||
public function testHandleFreshConfigFile()
|
||||
{
|
||||
Helper::createIniFile(CONF, $this->_options);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals($this->_options, $conf->get(), 'newly generated configuration is correct');
|
||||
}
|
||||
|
||||
public function testHandleMissingConfigFile()
|
||||
{
|
||||
@unlink(CONF);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals($this->_options, $conf->get(), 'returns correct defaults on missing file');
|
||||
}
|
||||
|
||||
@ -53,13 +53,13 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
public function testHandleBlankConfigFile()
|
||||
{
|
||||
file_put_contents(CONF, '');
|
||||
new Configuration;
|
||||
new Configuration();
|
||||
}
|
||||
|
||||
public function testHandleMinimalConfigFile()
|
||||
{
|
||||
file_put_contents(CONF, $this->_minimalConfig);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals($this->_options, $conf->get(), 'returns correct defaults on empty file');
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
public function testHandleInvalidSection()
|
||||
{
|
||||
file_put_contents(CONF, $this->_minimalConfig);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$conf->getKey('foo', 'bar');
|
||||
}
|
||||
|
||||
@ -81,14 +81,14 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
public function testHandleInvalidKey()
|
||||
{
|
||||
file_put_contents(CONF, $this->_minimalConfig);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$conf->getKey('foo');
|
||||
}
|
||||
|
||||
public function testHandleGetKey()
|
||||
{
|
||||
file_put_contents(CONF, $this->_minimalConfig);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals($this->_options['main']['sizelimit'], $conf->getKey('sizelimit'), 'get default size');
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
$options['expire_options']['foo'] = 'bar';
|
||||
$options['formatter_options'][] = 'foo';
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$original_options['expire_options']['foo'] = intval('bar');
|
||||
$original_options['formatter_options'][0] = 'foo';
|
||||
$this->assertEquals($original_options, $conf->get(), 'incorrect types are corrected');
|
||||
@ -117,7 +117,7 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
unset($options['expire_options']['1year']);
|
||||
unset($options['expire_options']['never']);
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$options['expire']['default'] = '5min';
|
||||
$this->assertEquals($options, $conf->get(), 'not overriding "missing" subkeys');
|
||||
}
|
||||
@ -127,12 +127,12 @@ class ConfigurationTest extends PHPUnit_Framework_TestCase
|
||||
$options = $this->_options;
|
||||
$options['model']['class'] = 'zerobin_data';
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals('Filesystem', $conf->getKey('class', 'model'), 'old data class gets renamed');
|
||||
|
||||
$options['model']['class'] = 'zerobin_db';
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$this->assertEquals('Database', $conf->getKey('class', 'model'), 'old db class gets renamed');
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* generates a config unit test class
|
||||
* generates a config unit test class.
|
||||
*
|
||||
* This generator is meant to test all possible configuration combinations
|
||||
* without having to write endless amounts of code manually.
|
||||
@ -9,327 +9,331 @@
|
||||
* DANGER: Too many options/settings and too high max iteration setting may trigger
|
||||
* a fork bomb. Please save your work before executing this script.
|
||||
*/
|
||||
|
||||
include 'Bootstrap.php';
|
||||
|
||||
$vrd = array('view', 'read', 'delete');
|
||||
$vcud = array('view', 'create', 'read', 'delete');
|
||||
$vrd = ['view', 'read', 'delete'];
|
||||
$vcud = ['view', 'create', 'read', 'delete'];
|
||||
|
||||
new ConfigurationTestGenerator(array(
|
||||
'main/discussion' => array(
|
||||
array(
|
||||
new ConfigurationTestGenerator([
|
||||
'main/discussion' => [
|
||||
[
|
||||
'setting' => true,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('steps' => $vrd),
|
||||
'type' => 'RegExp',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['steps' => $vrd],
|
||||
'type' => 'RegExp',
|
||||
'args' => [
|
||||
'#<div[^>]*id="opendisc"[^>]*>#',
|
||||
'$content',
|
||||
'outputs enabled discussion correctly'
|
||||
),
|
||||
), array(
|
||||
'conditions' => array('steps' => array('create'), 'traffic/limit' => 10),
|
||||
'settings' => array('$_POST["opendiscussion"] = "neither 1 nor 0"'),
|
||||
'type' => 'Equals',
|
||||
'args' => array(
|
||||
'outputs enabled discussion correctly',
|
||||
],
|
||||
], [
|
||||
'conditions' => ['steps' => ['create'], 'traffic/limit' => 10],
|
||||
'settings' => ['$_POST["opendiscussion"] = "neither 1 nor 0"'],
|
||||
'type' => 'Equals',
|
||||
'args' => [
|
||||
1,
|
||||
'$response["status"]',
|
||||
'when discussions are enabled, but invalid flag posted, fail to create paste'
|
||||
),
|
||||
), array(
|
||||
'conditions' => array('steps' => array('create'), 'traffic/limit' => 10),
|
||||
'settings' => array('$_POST["opendiscussion"] = "neither 1 nor 0"'),
|
||||
'type' => 'False',
|
||||
'args' => array(
|
||||
'when discussions are enabled, but invalid flag posted, fail to create paste',
|
||||
],
|
||||
], [
|
||||
'conditions' => ['steps' => ['create'], 'traffic/limit' => 10],
|
||||
'settings' => ['$_POST["opendiscussion"] = "neither 1 nor 0"'],
|
||||
'type' => 'False',
|
||||
'args' => [
|
||||
'$this->_model->exists(Helper::getPasteId())',
|
||||
'when discussions are enabled, but invalid flag posted, paste is not created'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => $vcud
|
||||
), array(
|
||||
'when discussions are enabled, but invalid flag posted, paste is not created',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vcud,
|
||||
], [
|
||||
'setting' => false,
|
||||
'tests' => array(
|
||||
array(
|
||||
'tests' => [
|
||||
[
|
||||
'type' => 'NotRegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<div[^>]*id="opendisc"[^>]*>#',
|
||||
'$content',
|
||||
'outputs disabled discussion correctly'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => $vrd
|
||||
),
|
||||
),
|
||||
'main/opendiscussion' => array(
|
||||
array(
|
||||
'outputs disabled discussion correctly',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
],
|
||||
],
|
||||
'main/opendiscussion' => [
|
||||
[
|
||||
'setting' => true,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('main/discussion' => true),
|
||||
'type' => 'RegExp',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['main/discussion' => true],
|
||||
'type' => 'RegExp',
|
||||
'args' => [
|
||||
'#<input[^>]+id="opendiscussion"[^>]*checked="checked"[^>]*>#',
|
||||
'$content',
|
||||
'outputs checked discussion correctly'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => $vrd
|
||||
), array(
|
||||
'outputs checked discussion correctly',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
], [
|
||||
'setting' => false,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('main/discussion' => true),
|
||||
'type' => 'NotRegExp',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['main/discussion' => true],
|
||||
'type' => 'NotRegExp',
|
||||
'args' => [
|
||||
'#<input[^>]+id="opendiscussion"[^>]*checked="checked"[^>]*>#',
|
||||
'$content',
|
||||
'outputs unchecked discussion correctly'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => $vrd
|
||||
),
|
||||
),
|
||||
'main/burnafterreadingselected' => array(
|
||||
array(
|
||||
'outputs unchecked discussion correctly',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
],
|
||||
],
|
||||
'main/burnafterreadingselected' => [
|
||||
[
|
||||
'setting' => true,
|
||||
'tests' => array(
|
||||
array(
|
||||
'tests' => [
|
||||
[
|
||||
'type' => 'RegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<input[^>]+id="burnafterreading"[^>]*checked="checked"[^>]*>#',
|
||||
'$content',
|
||||
'preselects burn after reading option',
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('view'),
|
||||
), array(
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['view'],
|
||||
], [
|
||||
'setting' => false,
|
||||
'tests' => array(
|
||||
array(
|
||||
'tests' => [
|
||||
[
|
||||
'type' => 'NotRegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<input[^>]+id="burnafterreading"[^>]*checked="checked"[^>]*>#',
|
||||
'$content',
|
||||
'burn after reading option is unchecked',
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('view'),
|
||||
),
|
||||
),
|
||||
'main/password' => array(
|
||||
array(
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['view'],
|
||||
],
|
||||
],
|
||||
'main/password' => [
|
||||
[
|
||||
'setting' => true,
|
||||
'tests' => array(
|
||||
array(
|
||||
'tests' => [
|
||||
[
|
||||
'type' => 'RegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<div[^>]*id="password"[^>]*>#',
|
||||
'$content',
|
||||
'outputs password input correctly'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => $vrd
|
||||
), array(
|
||||
'outputs password input correctly',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
], [
|
||||
'setting' => false,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('main/discussion' => true),
|
||||
'type' => 'NotRegExp',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['main/discussion' => true],
|
||||
'type' => 'NotRegExp',
|
||||
'args' => [
|
||||
'#<div[^>]*id="password"[^>]*>#',
|
||||
'$content',
|
||||
'removes password input correctly'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => $vrd
|
||||
),
|
||||
),
|
||||
'main/template' => array(
|
||||
array(
|
||||
'removes password input correctly',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
],
|
||||
],
|
||||
'main/template' => [
|
||||
[
|
||||
'setting' => 'page',
|
||||
'tests' => array(
|
||||
array(
|
||||
'tests' => [
|
||||
[
|
||||
'type' => 'RegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/privatebin\.css\\?\d+\.\d+"[^>]*/>#',
|
||||
'$content',
|
||||
'outputs "page" stylesheet correctly',
|
||||
),
|
||||
), array(
|
||||
],
|
||||
], [
|
||||
'type' => 'NotRegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/bootstrap/bootstrap-\d[\d\.]+\d\.css"[^>]*/>#',
|
||||
'$content',
|
||||
'removes "bootstrap" stylesheet correctly',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
), array(
|
||||
], [
|
||||
'setting' => 'bootstrap',
|
||||
'tests' => array(
|
||||
array(
|
||||
'tests' => [
|
||||
[
|
||||
'type' => 'NotRegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/privatebin\.css\\?\d+\.\d+"[^>]*/>#',
|
||||
'$content',
|
||||
'removes "page" stylesheet correctly',
|
||||
),
|
||||
), array(
|
||||
],
|
||||
], [
|
||||
'type' => 'RegExp',
|
||||
'args' => array(
|
||||
'args' => [
|
||||
'#<link[^>]+type="text/css"[^>]+rel="stylesheet"[^>]+href="css/bootstrap/bootstrap-\d[\d\.]+\d\.css"[^>]*/>#',
|
||||
'$content',
|
||||
'outputs "bootstrap" stylesheet correctly',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => $vrd,
|
||||
),
|
||||
),
|
||||
'main/sizelimit' => array(
|
||||
array(
|
||||
],
|
||||
],
|
||||
'main/sizelimit' => [
|
||||
[
|
||||
'setting' => 10,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('steps' => array('create'), 'traffic/limit' => 10),
|
||||
'type' => 'Equals',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['steps' => ['create'], 'traffic/limit' => 10],
|
||||
'type' => 'Equals',
|
||||
'args' => [
|
||||
1,
|
||||
'$response["status"]',
|
||||
'when sizelimit limit exceeded, fail to create paste'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('create')
|
||||
), array(
|
||||
'when sizelimit limit exceeded, fail to create paste',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['create'],
|
||||
], [
|
||||
'setting' => 2097152,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('steps' => array('create'), 'traffic/limit' => 0, 'main/burnafterreadingselected' => true),
|
||||
'settings' => array('sleep(3)'),
|
||||
'type' => 'Equals',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['steps' => ['create'], 'traffic/limit' => 0, 'main/burnafterreadingselected' => true],
|
||||
'settings' => ['sleep(3)'],
|
||||
'type' => 'Equals',
|
||||
'args' => [
|
||||
0,
|
||||
'$response["status"]',
|
||||
'when sizelimit limit is not reached, successfully create paste'
|
||||
),
|
||||
), array(
|
||||
'conditions' => array('steps' => array('create'), 'traffic/limit' => 0, 'main/burnafterreadingselected' => true),
|
||||
'settings' => array('sleep(3)'),
|
||||
'type' => 'True',
|
||||
'args' => array(
|
||||
'when sizelimit limit is not reached, successfully create paste',
|
||||
],
|
||||
], [
|
||||
'conditions' => ['steps' => ['create'], 'traffic/limit' => 0, 'main/burnafterreadingselected' => true],
|
||||
'settings' => ['sleep(3)'],
|
||||
'type' => 'True',
|
||||
'args' => [
|
||||
'$this->_model->exists($response["id"])',
|
||||
'when sizelimit limit is not reached, paste exists after posting data'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('create')
|
||||
),
|
||||
),
|
||||
'traffic/limit' => array(
|
||||
array(
|
||||
'when sizelimit limit is not reached, paste exists after posting data',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['create'],
|
||||
],
|
||||
],
|
||||
'traffic/limit' => [
|
||||
[
|
||||
'setting' => 0,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('steps' => array('create'), 'main/sizelimit' => 2097152),
|
||||
'type' => 'Equals',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['steps' => ['create'], 'main/sizelimit' => 2097152],
|
||||
'type' => 'Equals',
|
||||
'args' => [
|
||||
0,
|
||||
'$response["status"]',
|
||||
'when traffic limit is disabled, successfully create paste'
|
||||
),
|
||||
), array(
|
||||
'conditions' => array('steps' => array('create'), 'main/sizelimit' => 2097152),
|
||||
'type' => 'True',
|
||||
'args' => array(
|
||||
'when traffic limit is disabled, successfully create paste',
|
||||
],
|
||||
], [
|
||||
'conditions' => ['steps' => ['create'], 'main/sizelimit' => 2097152],
|
||||
'type' => 'True',
|
||||
'args' => [
|
||||
'$this->_model->exists($response["id"])',
|
||||
'when traffic limit is disabled, paste exists after posting data'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('create')
|
||||
), array(
|
||||
'when traffic limit is disabled, paste exists after posting data',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['create'],
|
||||
], [
|
||||
'setting' => 10,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('steps' => array('create')),
|
||||
'type' => 'Equals',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['steps' => ['create']],
|
||||
'type' => 'Equals',
|
||||
'args' => [
|
||||
1,
|
||||
'$response["status"]',
|
||||
'when traffic limit is on and we do not wait, fail to create paste'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('create')
|
||||
), array(
|
||||
'when traffic limit is on and we do not wait, fail to create paste',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['create'],
|
||||
], [
|
||||
'setting' => 2,
|
||||
'tests' => array(
|
||||
array(
|
||||
'conditions' => array('steps' => array('create'), 'main/sizelimit' => 2097152),
|
||||
'settings' => array('sleep(3)'),
|
||||
'type' => 'Equals',
|
||||
'args' => array(
|
||||
'tests' => [
|
||||
[
|
||||
'conditions' => ['steps' => ['create'], 'main/sizelimit' => 2097152],
|
||||
'settings' => ['sleep(3)'],
|
||||
'type' => 'Equals',
|
||||
'args' => [
|
||||
0,
|
||||
'$response["status"]',
|
||||
'when traffic limit is on and we wait, successfully create paste'
|
||||
),
|
||||
), array(
|
||||
'conditions' => array('steps' => array('create'), 'main/sizelimit' => 2097152),
|
||||
'settings' => array('sleep(3)'),
|
||||
'type' => 'True',
|
||||
'args' => array(
|
||||
'when traffic limit is on and we wait, successfully create paste',
|
||||
],
|
||||
], [
|
||||
'conditions' => ['steps' => ['create'], 'main/sizelimit' => 2097152],
|
||||
'settings' => ['sleep(3)'],
|
||||
'type' => 'True',
|
||||
'args' => [
|
||||
'$this->_model->exists($response["id"])',
|
||||
'when traffic limit is on and we wait, paste exists after posting data'
|
||||
),
|
||||
),
|
||||
),
|
||||
'affects' => array('create')
|
||||
),
|
||||
),
|
||||
));
|
||||
'when traffic limit is on and we wait, paste exists after posting data',
|
||||
],
|
||||
],
|
||||
],
|
||||
'affects' => ['create'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
class ConfigurationTestGenerator
|
||||
{
|
||||
/**
|
||||
* endless loop protection, since we're working with a recursive function,
|
||||
* creating factorial configurations
|
||||
* creating factorial configurations.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MAX_ITERATIONS = 2000;
|
||||
|
||||
/**
|
||||
* options to test
|
||||
* options to test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_options;
|
||||
|
||||
/**
|
||||
* iteration count to guarantee timely end
|
||||
* iteration count to guarantee timely end.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_iterationCount = 0;
|
||||
|
||||
/**
|
||||
* generated configurations
|
||||
* generated configurations.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_configurations = array(
|
||||
array('options' => array(), 'tests' => array(), 'affects' => array())
|
||||
);
|
||||
private $_configurations = [
|
||||
['options' => [], 'tests' => [], 'affects' => []],
|
||||
];
|
||||
|
||||
/**
|
||||
* constructor, generates the configuration test
|
||||
* constructor, generates the configuration test.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($options)
|
||||
@ -341,7 +345,7 @@ class ConfigurationTestGenerator
|
||||
}
|
||||
|
||||
/**
|
||||
* write configuration test file based on generated configuration array
|
||||
* write configuration test file based on generated configuration array.
|
||||
*/
|
||||
private function _writeConfigurationTest()
|
||||
{
|
||||
@ -351,7 +355,7 @@ class ConfigurationTestGenerator
|
||||
$fullOptions = array_replace_recursive($defaultOptions, $conf['options']);
|
||||
$options = Helper::varExportMin($fullOptions, true);
|
||||
foreach ($conf['affects'] as $step) {
|
||||
$testCode = $preCode = array();
|
||||
$testCode = $preCode = [];
|
||||
foreach ($conf['tests'] as $tests) {
|
||||
foreach ($tests[0] as $test) {
|
||||
// skip if test does not affect this step
|
||||
@ -376,7 +380,7 @@ class ConfigurationTestGenerator
|
||||
$preCode[$setting] = $setting;
|
||||
}
|
||||
}
|
||||
$args = array();
|
||||
$args = [];
|
||||
foreach ($test['args'] as $arg) {
|
||||
if (is_string($arg) && strpos($arg, '$') === 0) {
|
||||
$args[] = $arg;
|
||||
@ -384,7 +388,7 @@ class ConfigurationTestGenerator
|
||||
$args[] = Helper::varExportMin($arg, true);
|
||||
}
|
||||
}
|
||||
$testCode[] = array($test['type'], implode(', ', $args));
|
||||
$testCode[] = [$test['type'], implode(', ', $args)];
|
||||
}
|
||||
}
|
||||
$code .= $this->_getFunction(
|
||||
@ -392,12 +396,12 @@ class ConfigurationTestGenerator
|
||||
);
|
||||
}
|
||||
}
|
||||
$code .= '}' . PHP_EOL;
|
||||
$code .= '}'.PHP_EOL;
|
||||
file_put_contents('ConfigurationCombinationsTest.php', $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* get header of configuration test file
|
||||
* get header of configuration test file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -458,30 +462,32 @@ EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* get unit tests function block
|
||||
* get unit tests function block.
|
||||
*
|
||||
* @param string $step
|
||||
* @param int $key
|
||||
* @param array $options
|
||||
* @param array $preCode
|
||||
* @param array $testCode
|
||||
* @param int $key
|
||||
* @param array $options
|
||||
* @param array $preCode
|
||||
* @param array $testCode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _getFunction($step, $key, &$options, $preCode, $testCode)
|
||||
{
|
||||
if (count($testCode) == 0) {
|
||||
echo "skipping creation of test$step$key, no valid tests found for configuration: $options". PHP_EOL;
|
||||
echo "skipping creation of test$step$key, no valid tests found for configuration: $options".PHP_EOL;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$preString = $testString = '';
|
||||
foreach ($preCode as $setting) {
|
||||
$preString .= " $setting;" . PHP_EOL;
|
||||
$preString .= " $setting;".PHP_EOL;
|
||||
}
|
||||
foreach ($testCode as $test) {
|
||||
$type = $test[0];
|
||||
$args = $test[1];
|
||||
$testString .= " \$this->assert$type($args);" . PHP_EOL;
|
||||
$testString .= " \$this->assert$type($args);".PHP_EOL;
|
||||
}
|
||||
$code = <<<EOT
|
||||
/**
|
||||
@ -495,7 +501,7 @@ EOT;
|
||||
// step specific initialization
|
||||
switch ($step) {
|
||||
case 'Create':
|
||||
$code .= PHP_EOL . <<<'EOT'
|
||||
$code .= PHP_EOL.<<<'EOT'
|
||||
$_POST = Helper::getPaste();
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
@ -504,13 +510,13 @@ EOT;
|
||||
EOT;
|
||||
break;
|
||||
case 'Read':
|
||||
$code .= PHP_EOL . <<<'EOT'
|
||||
$code .= PHP_EOL.<<<'EOT'
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
EOT;
|
||||
break;
|
||||
case 'Delete':
|
||||
$code .= PHP_EOL . <<<'EOT'
|
||||
$code .= PHP_EOL.<<<'EOT'
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||
$_GET['pasteid'] = Helper::getPasteId();
|
||||
@ -520,7 +526,7 @@ EOT;
|
||||
}
|
||||
|
||||
// all steps
|
||||
$code .= PHP_EOL . $preString;
|
||||
$code .= PHP_EOL.$preString;
|
||||
$code .= <<<'EOT'
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
@ -558,13 +564,15 @@ EOT;
|
||||
EOT;
|
||||
break;
|
||||
}
|
||||
return $code . PHP_EOL . PHP_EOL . $testString . ' }' . PHP_EOL . PHP_EOL;
|
||||
|
||||
return $code.PHP_EOL.PHP_EOL.$testString.' }'.PHP_EOL.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* recursive function to generate configurations based on options
|
||||
* recursive function to generate configurations based on options.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function _generateConfigurations()
|
||||
@ -572,6 +580,7 @@ EOT;
|
||||
// recursive factorial function
|
||||
if (++$this->_iterationCount > self::MAX_ITERATIONS) {
|
||||
echo 'max iterations reached, stopping', PHP_EOL;
|
||||
|
||||
return $this->_configurations;
|
||||
}
|
||||
echo "generateConfigurations: iteration $this->_iterationCount", PHP_EOL;
|
||||
@ -582,7 +591,7 @@ EOT;
|
||||
list($section, $option) = explode('/', $path);
|
||||
for ($c = 0, $max = count($this->_configurations); $c < $max; ++$c) {
|
||||
if (!array_key_exists($section, $this->_configurations[$c]['options'])) {
|
||||
$this->_configurations[$c]['options'][$section] = array();
|
||||
$this->_configurations[$c]['options'][$section] = [];
|
||||
}
|
||||
if (count($settings) == 0) {
|
||||
throw new Exception("Check your \$options: option $option has no settings!");
|
||||
@ -598,23 +607,27 @@ EOT;
|
||||
}
|
||||
reset($settings);
|
||||
}
|
||||
|
||||
return $this->_generateConfigurations();
|
||||
}
|
||||
|
||||
/**
|
||||
* add a setting to the given configuration
|
||||
* add a setting to the given configuration.
|
||||
*
|
||||
* @param array $configuration
|
||||
* @param array $setting
|
||||
* @param array $configuration
|
||||
* @param array $setting
|
||||
* @param string $section
|
||||
* @param string $option
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function _addSetting(&$configuration, &$setting, &$section, &$option)
|
||||
{
|
||||
if (++$this->_iterationCount > self::MAX_ITERATIONS) {
|
||||
echo 'max iterations reached, stopping', PHP_EOL;
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
echo "addSetting: iteration $this->_iterationCount", PHP_EOL;
|
||||
@ -626,12 +639,13 @@ EOT;
|
||||
throw new Exception("Endless loop or error in options detected: option '$option' already exists with setting '$val' in one of the configurations!");
|
||||
}
|
||||
$configuration['options'][$section][$option] = $setting['setting'];
|
||||
$configuration['tests'][$option] = array($setting['tests'], $setting['affects']);
|
||||
$configuration['tests'][$option] = [$setting['tests'], $setting['affects']];
|
||||
foreach ($setting['affects'] as $affects) {
|
||||
if (!in_array($affects, $configuration['affects'])) {
|
||||
$configuration['affects'][] = $affects;
|
||||
}
|
||||
}
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
}
|
||||
|
@ -9,17 +9,17 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
private $_path;
|
||||
|
||||
private $_options = array(
|
||||
private $_options = [
|
||||
'dsn' => 'sqlite::memory:',
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
];
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'privatebin_data';
|
||||
$this->_model = Database::getInstance($this->_options);
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
|
||||
// storing pastes
|
||||
$paste = Helper::getPaste(array('expire_date' => 1344803344));
|
||||
$paste = Helper::getPaste(['expire_date' => 1344803344]);
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertTrue($this->_model->create(Helper::getPasteId(), $paste), 'store new paste');
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after storing it');
|
||||
@ -51,7 +51,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
$comment->id = Helper::getCommentId();
|
||||
$comment->parentid = Helper::getPasteId();
|
||||
$this->assertEquals(
|
||||
array($comment->meta->postdate => $comment),
|
||||
[$comment->meta->postdate => $comment],
|
||||
$this->_model->readComments(Helper::getPasteId())
|
||||
);
|
||||
|
||||
@ -65,7 +65,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
public function testDatabaseBasedAttachmentStoreWorks()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$original = $paste = Helper::getPasteWithAttachment(array('expire_date' => 1344803344));
|
||||
$original = $paste = Helper::getPasteWithAttachment(['expire_date' => 1344803344]);
|
||||
$paste['meta']['burnafterreading'] = $original['meta']['burnafterreading'] = true;
|
||||
$paste['meta']['attachment'] = $paste['attachment'];
|
||||
$paste['meta']['attachmentname'] = $paste['attachmentname'];
|
||||
@ -80,15 +80,15 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
public function testPurge()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$expired = Helper::getPaste(array('expire_date' => 1344803344));
|
||||
$paste = Helper::getPaste(array('expire_date' => time() + 3600));
|
||||
$keys = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'x', 'y', 'z');
|
||||
$ids = array();
|
||||
$expired = Helper::getPaste(['expire_date' => 1344803344]);
|
||||
$paste = Helper::getPaste(['expire_date' => time() + 3600]);
|
||||
$keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'x', 'y', 'z'];
|
||||
$ids = [];
|
||||
foreach ($keys as $key) {
|
||||
$ids[$key] = substr(md5($key), 0, 16);
|
||||
$this->_model->delete($ids[$key]);
|
||||
$this->assertFalse($this->_model->exists($ids[$key]), "paste $key does not yet exist");
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
if (in_array($key, ['x', 'y', 'z'])) {
|
||||
$this->assertTrue($this->_model->create($ids[$key], $paste), "store $key paste");
|
||||
} else {
|
||||
$this->assertTrue($this->_model->create($ids[$key], $expired), "store $key paste");
|
||||
@ -97,7 +97,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
$this->_model->purge(10);
|
||||
foreach ($ids as $key => $id) {
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
if (in_array($key, ['x', 'y', 'z'])) {
|
||||
$this->assertTrue($this->_model->exists($id), "paste $key exists after purge");
|
||||
$this->_model->delete($id);
|
||||
} else {
|
||||
@ -111,10 +111,10 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetIbmInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
Database::getInstance([
|
||||
'dsn' => 'ibm:', 'usr' => null, 'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
));
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,10 +122,10 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetInformixInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
Database::getInstance([
|
||||
'dsn' => 'informix:', 'usr' => null, 'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
));
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,10 +133,10 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetMssqlInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
Database::getInstance([
|
||||
'dsn' => 'mssql:', 'usr' => null, 'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
));
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,10 +144,10 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetMysqlInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
Database::getInstance([
|
||||
'dsn' => 'mysql:', 'usr' => null, 'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
));
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,10 +155,10 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetOciInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
Database::getInstance([
|
||||
'dsn' => 'oci:', 'usr' => null, 'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
));
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,10 +166,10 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetPgsqlInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
Database::getInstance([
|
||||
'dsn' => 'pgsql:', 'usr' => null, 'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
|
||||
));
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,9 +178,9 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetFooInstance()
|
||||
{
|
||||
Database::getInstance(array(
|
||||
'dsn' => 'foo:', 'usr' => null, 'pwd' => null, 'opt' => null
|
||||
));
|
||||
Database::getInstance([
|
||||
'dsn' => 'foo:', 'usr' => null, 'pwd' => null, 'opt' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,13 +230,15 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
public function testOldAttachments()
|
||||
{
|
||||
mkdir($this->_path);
|
||||
$path = $this->_path . DIRECTORY_SEPARATOR . 'attachement-test.sq3';
|
||||
if (is_file($path)) unlink($path);
|
||||
$this->_options['dsn'] = 'sqlite:' . $path;
|
||||
$path = $this->_path.DIRECTORY_SEPARATOR.'attachement-test.sq3';
|
||||
if (is_file($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
$this->_options['dsn'] = 'sqlite:'.$path;
|
||||
$this->_options['tbl'] = 'bar_';
|
||||
$model = Database::getInstance($this->_options);
|
||||
|
||||
$original = $paste = Helper::getPasteWithAttachment(array('expire_date' => 1344803344));
|
||||
$original = $paste = Helper::getPasteWithAttachment(['expire_date' => 1344803344]);
|
||||
$paste['meta']['attachment'] = $paste['attachment'];
|
||||
$paste['meta']['attachmentname'] = $paste['attachmentname'];
|
||||
unset($paste['attachment'], $paste['attachmentname']);
|
||||
@ -250,7 +252,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
);
|
||||
$statement = $db->prepare('INSERT INTO bar_paste VALUES(?,?,?,?,?,?,?,?,?)');
|
||||
$statement->execute(
|
||||
array(
|
||||
[
|
||||
Helper::getPasteId(),
|
||||
$paste['data'],
|
||||
$paste['meta']['postdate'],
|
||||
@ -260,7 +262,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
json_encode($meta),
|
||||
null,
|
||||
null,
|
||||
)
|
||||
]
|
||||
);
|
||||
$statement->closeCursor();
|
||||
|
||||
@ -273,9 +275,11 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
public function testTableUpgrade()
|
||||
{
|
||||
mkdir($this->_path);
|
||||
$path = $this->_path . DIRECTORY_SEPARATOR . 'db-test.sq3';
|
||||
if (is_file($path)) unlink($path);
|
||||
$this->_options['dsn'] = 'sqlite:' . $path;
|
||||
$path = $this->_path.DIRECTORY_SEPARATOR.'db-test.sq3';
|
||||
if (is_file($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
$this->_options['dsn'] = 'sqlite:'.$path;
|
||||
$this->_options['tbl'] = 'foo_';
|
||||
$db = new PDO(
|
||||
$this->_options['dsn'],
|
||||
@ -284,29 +288,29 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
$this->_options['opt']
|
||||
);
|
||||
$db->exec(
|
||||
'CREATE TABLE foo_paste ( ' .
|
||||
'dataid CHAR(16), ' .
|
||||
'data TEXT, ' .
|
||||
'postdate INT, ' .
|
||||
'expiredate INT, ' .
|
||||
'opendiscussion INT, ' .
|
||||
'CREATE TABLE foo_paste ( '.
|
||||
'dataid CHAR(16), '.
|
||||
'data TEXT, '.
|
||||
'postdate INT, '.
|
||||
'expiredate INT, '.
|
||||
'opendiscussion INT, '.
|
||||
'burnafterreading INT );'
|
||||
);
|
||||
$db->exec(
|
||||
'CREATE TABLE foo_comment ( ' .
|
||||
"dataid CHAR(16) NOT NULL, " .
|
||||
'pasteid CHAR(16), ' .
|
||||
'parentid CHAR(16), ' .
|
||||
'data BLOB, ' .
|
||||
'nickname BLOB, ' .
|
||||
'vizhash BLOB, ' .
|
||||
"postdate INT );"
|
||||
'CREATE TABLE foo_comment ( '.
|
||||
'dataid CHAR(16) NOT NULL, '.
|
||||
'pasteid CHAR(16), '.
|
||||
'parentid CHAR(16), '.
|
||||
'data BLOB, '.
|
||||
'nickname BLOB, '.
|
||||
'vizhash BLOB, '.
|
||||
'postdate INT );'
|
||||
);
|
||||
$this->assertInstanceOf(Database::class, Database::getInstance($this->_options));
|
||||
|
||||
// check if version number was upgraded in created configuration table
|
||||
$statement = $db->prepare('SELECT value FROM foo_config WHERE id LIKE ?');
|
||||
$statement->execute(array('VERSION'));
|
||||
$statement->execute(['VERSION']);
|
||||
$result = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
$statement->closeCursor();
|
||||
$this->assertEquals(PrivateBin::VERSION, $result['value']);
|
||||
|
@ -11,8 +11,8 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
$this->_path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(['dir' => $this->_path]);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
@ -26,7 +26,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
|
||||
// storing pastes
|
||||
$paste = Helper::getPaste(array('expire_date' => 1344803344));
|
||||
$paste = Helper::getPaste(['expire_date' => 1344803344]);
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertTrue($this->_model->create(Helper::getPasteId(), $paste), 'store new paste');
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after storing it');
|
||||
@ -41,7 +41,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
$comment->id = Helper::getCommentId();
|
||||
$comment->parentid = Helper::getPasteId();
|
||||
$this->assertEquals(
|
||||
array($comment->meta->postdate => $comment),
|
||||
[$comment->meta->postdate => $comment],
|
||||
$this->_model->readComments(Helper::getPasteId())
|
||||
);
|
||||
|
||||
@ -55,7 +55,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
public function testFileBasedAttachmentStoreWorks()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$original = $paste = Helper::getPasteWithAttachment(array('expire_date' => 1344803344));
|
||||
$original = $paste = Helper::getPasteWithAttachment(['expire_date' => 1344803344]);
|
||||
$paste['meta']['attachment'] = $paste['attachment'];
|
||||
$paste['meta']['attachmentname'] = $paste['attachmentname'];
|
||||
unset($paste['attachment'], $paste['attachmentname']);
|
||||
@ -68,15 +68,15 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testPurge()
|
||||
{
|
||||
mkdir($this->_path . DIRECTORY_SEPARATOR . '00', 0777, true);
|
||||
$expired = Helper::getPaste(array('expire_date' => 1344803344));
|
||||
$paste = Helper::getPaste(array('expire_date' => time() + 3600));
|
||||
$keys = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'x', 'y', 'z');
|
||||
$ids = array();
|
||||
mkdir($this->_path.DIRECTORY_SEPARATOR.'00', 0777, true);
|
||||
$expired = Helper::getPaste(['expire_date' => 1344803344]);
|
||||
$paste = Helper::getPaste(['expire_date' => time() + 3600]);
|
||||
$keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'x', 'y', 'z'];
|
||||
$ids = [];
|
||||
foreach ($keys as $key) {
|
||||
$ids[$key] = substr(md5($key), 0, 16);
|
||||
$this->assertFalse($this->_model->exists($ids[$key]), "paste $key does not yet exist");
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
if (in_array($key, ['x', 'y', 'z'])) {
|
||||
$this->assertTrue($this->_model->create($ids[$key], $paste), "store $key paste");
|
||||
} else {
|
||||
$this->assertTrue($this->_model->create($ids[$key], $expired), "store $key paste");
|
||||
@ -85,7 +85,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
$this->_model->purge(10);
|
||||
foreach ($ids as $key => $id) {
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
if (in_array($key, ['x', 'y', 'z'])) {
|
||||
$this->assertTrue($this->_model->exists($id), "paste $key exists after purge");
|
||||
$this->_model->delete($id);
|
||||
} else {
|
||||
@ -101,7 +101,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
public function testErrorDetection()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$paste = Helper::getPaste(array('formatter' => "Invalid UTF-8 sequence: \xB1\x31"));
|
||||
$paste = Helper::getPaste(['formatter' => "Invalid UTF-8 sequence: \xB1\x31"]);
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertFalse($this->_model->create(Helper::getPasteId(), $paste), 'unable to store broken paste');
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does still not exist');
|
||||
@ -114,7 +114,7 @@ class FilesystemTest extends PHPUnit_Framework_TestCase
|
||||
public function testCommentErrorDetection()
|
||||
{
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
$comment = Helper::getComment(array('formatter' => "Invalid UTF-8 sequence: \xB1\x31"));
|
||||
$comment = Helper::getComment(['formatter' => "Invalid UTF-8 sequence: \xB1\x31"]);
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
|
||||
$this->assertTrue($this->_model->create(Helper::getPasteId(), Helper::getPaste()), 'store new paste');
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after storing it');
|
||||
|
@ -7,8 +7,8 @@ class FilterTest extends PHPUnit_Framework_TestCase
|
||||
public function testFilterStripsSlashesDeeply()
|
||||
{
|
||||
$this->assertEquals(
|
||||
array("f'oo", "b'ar", array("fo'o", "b'ar")),
|
||||
Filter::stripslashesDeep(array("f\\'oo", "b\\'ar", array("fo\\'o", "b\\'ar")))
|
||||
["f'oo", "b'ar", ["fo'o", "b'ar"]],
|
||||
Filter::stripslashesDeep(["f\\'oo", "b\\'ar", ["fo\\'o", "b\\'ar"]])
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,13 @@ use PrivateBin\I18n;
|
||||
|
||||
class I18nTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $_translations = array();
|
||||
private $_translations = [];
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_translations = json_decode(
|
||||
file_get_contents(PATH . 'i18n' . DIRECTORY_SEPARATOR . 'de.json'),
|
||||
file_get_contents(PATH.'i18n'.DIRECTORY_SEPARATOR.'de.json'),
|
||||
true
|
||||
);
|
||||
}
|
||||
@ -34,7 +34,7 @@ class I18nTest extends PHPUnit_Framework_TestCase
|
||||
I18n::loadTranslations();
|
||||
$this->assertEquals($this->_translations['en'], I18n::_('en'), 'browser language de');
|
||||
$this->assertEquals('0 Stunden', I18n::_('%d hours', 0), '0 hours in german');
|
||||
$this->assertEquals('1 Stunde', I18n::_('%d hours', 1), '1 hour in german');
|
||||
$this->assertEquals('1 Stunde', I18n::_('%d hours', 1), '1 hour in german');
|
||||
$this->assertEquals('2 Stunden', I18n::_('%d hours', 2), '2 hours in french');
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ class I18nTest extends PHPUnit_Framework_TestCase
|
||||
I18n::loadTranslations();
|
||||
$this->assertEquals($this->_translations['en'], I18n::_('en'), 'browser language de');
|
||||
$this->assertEquals('0 Stunden', I18n::_('%d hours', 0), '0 hours in german');
|
||||
$this->assertEquals('1 Stunde', I18n::_('%d hours', 1), '1 hour in german');
|
||||
$this->assertEquals('1 Stunde', I18n::_('%d hours', 1), '1 hour in german');
|
||||
$this->assertEquals('2 Stunden', I18n::_('%d hours', 2), '2 hours in french');
|
||||
}
|
||||
|
||||
@ -53,8 +53,8 @@ class I18nTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'fr-CH,fr;q=0.8,en-GB;q=0.6,en-US;q=0.4,en;q=0.2';
|
||||
I18n::loadTranslations();
|
||||
$this->assertEquals('fr', I18n::_('en'), 'browser language fr');
|
||||
$this->assertEquals('0 heure', I18n::_('%d hours', 0), '0 hours in french');
|
||||
$this->assertEquals('1 heure', I18n::_('%d hours', 1), '1 hour in french');
|
||||
$this->assertEquals('0 heure', I18n::_('%d hours', 0), '0 hours in french');
|
||||
$this->assertEquals('1 heure', I18n::_('%d hours', 1), '1 hour in french');
|
||||
$this->assertEquals('2 heures', I18n::_('%d hours', 2), '2 hours in french');
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\PrivateBin;
|
||||
use PrivateBin\Request;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
|
||||
class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -15,8 +15,8 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/* Setup Routine */
|
||||
Helper::confBackup();
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
$this->_path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(['dir' => $this->_path]);
|
||||
ServerSalt::setPath($this->_path);
|
||||
$this->reset();
|
||||
}
|
||||
@ -30,9 +30,9 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$_POST = array();
|
||||
$_GET = array();
|
||||
$_SERVER = array();
|
||||
$_POST = [];
|
||||
$_GET = [];
|
||||
$_SERVER = [];
|
||||
if ($this->_model->exists(Helper::getPasteId())) {
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
}
|
||||
@ -60,12 +60,12 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
$this->assertEquals(0, $response['status'], 'outputs status');
|
||||
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertStringEndsWith('?'.$response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
|
||||
$paste = $this->_model->read($response['id']);
|
||||
$this->assertEquals(
|
||||
@ -95,13 +95,13 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'PUT';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
$this->assertEquals(0, $response['status'], 'outputs status');
|
||||
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputted paste ID matches input');
|
||||
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertStringEndsWith('?'.$response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
|
||||
$paste = $this->_model->read($response['id']);
|
||||
$this->assertEquals(
|
||||
@ -121,15 +121,15 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||
$paste = $this->_model->read(Helper::getPasteId());
|
||||
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
||||
file_put_contents($file, http_build_query(array(
|
||||
file_put_contents($file, http_build_query([
|
||||
'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste->meta->salt),
|
||||
)));
|
||||
]));
|
||||
Request::setInputStream($file);
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'DELETE';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -146,15 +146,15 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||
$paste = $this->_model->read(Helper::getPasteId());
|
||||
$_POST = array(
|
||||
'action' => 'delete',
|
||||
$_POST = [
|
||||
'action' => 'delete',
|
||||
'deletetoken' => hash_hmac('sha256', Helper::getPasteId(), $paste->meta->salt),
|
||||
);
|
||||
];
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -177,13 +177,13 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
$this->assertEquals(0, $response['status'], 'outputs success status');
|
||||
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputs data correctly');
|
||||
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertStringEndsWith('?'.$response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertEquals($paste['data'], $response['data'], 'outputs data correctly');
|
||||
$this->assertEquals($paste['meta']['attachment'], $response['attachment'], 'outputs attachment correctly');
|
||||
$this->assertEquals($paste['meta']['attachmentname'], $response['attachmentname'], 'outputs attachmentname correctly');
|
||||
@ -204,13 +204,13 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), $paste);
|
||||
$_GET['jsonld'] = 'paste';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertEquals(str_replace(
|
||||
'?jsonld=',
|
||||
'/?jsonld=',
|
||||
file_get_contents(PUBLIC_PATH . '/js/paste.jsonld')
|
||||
file_get_contents(PUBLIC_PATH.'/js/paste.jsonld')
|
||||
), $content, 'outputs data correctly');
|
||||
}
|
||||
|
||||
@ -224,13 +224,13 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), $paste);
|
||||
$_GET['jsonld'] = 'comment';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertEquals(str_replace(
|
||||
'?jsonld=',
|
||||
'/?jsonld=',
|
||||
file_get_contents(PUBLIC_PATH . '/js/comment.jsonld')
|
||||
file_get_contents(PUBLIC_PATH.'/js/comment.jsonld')
|
||||
), $content, 'outputs data correctly');
|
||||
}
|
||||
|
||||
@ -244,13 +244,13 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), $paste);
|
||||
$_GET['jsonld'] = 'pastemeta';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertEquals(str_replace(
|
||||
'?jsonld=',
|
||||
'/?jsonld=',
|
||||
file_get_contents(PUBLIC_PATH . '/js/pastemeta.jsonld')
|
||||
file_get_contents(PUBLIC_PATH.'/js/pastemeta.jsonld')
|
||||
), $content, 'outputs data correctly');
|
||||
}
|
||||
|
||||
@ -264,13 +264,13 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), $paste);
|
||||
$_GET['jsonld'] = 'commentmeta';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertEquals(str_replace(
|
||||
'?jsonld=',
|
||||
'/?jsonld=',
|
||||
file_get_contents(PUBLIC_PATH . '/js/commentmeta.jsonld')
|
||||
file_get_contents(PUBLIC_PATH.'/js/commentmeta.jsonld')
|
||||
), $content, 'outputs data correctly');
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ class JsonApiTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), $paste);
|
||||
$_GET['jsonld'] = '../cfg/conf.ini';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertEquals('{}', $content, 'does not output nasty data');
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Identicon\Identicon;
|
||||
use PrivateBin\Configuration;
|
||||
use PrivateBin\Data\Database;
|
||||
use PrivateBin\Model;
|
||||
@ -7,7 +8,6 @@ use PrivateBin\Model\Paste;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
use PrivateBin\Vizhash16x16;
|
||||
use Identicon\Identicon;
|
||||
|
||||
class ModelTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -21,23 +21,25 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/* Setup Routine */
|
||||
Helper::confRestore();
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
if (!is_dir($this->_path)) mkdir($this->_path);
|
||||
$this->_path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'privatebin_data';
|
||||
if (!is_dir($this->_path)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
ServerSalt::setPath($this->_path);
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['purge']['limit'] = 0;
|
||||
$options['model'] = array(
|
||||
$options['model'] = [
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
];
|
||||
$options['model_options'] = [
|
||||
'dsn' => 'sqlite::memory:',
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
];
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$this->_conf = new Configuration;
|
||||
$this->_conf = new Configuration();
|
||||
$this->_model = new Model($this->_conf);
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
}
|
||||
@ -67,7 +69,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($paste->exists(), 'paste exists after storing it');
|
||||
$paste = $paste->get();
|
||||
$this->assertEquals($pasteData['data'], $paste->data);
|
||||
foreach (array('opendiscussion', 'formatter') as $key) {
|
||||
foreach (['opendiscussion', 'formatter'] as $key) {
|
||||
$this->assertEquals($pasteData['meta'][$key], $paste->meta->$key);
|
||||
}
|
||||
|
||||
@ -92,7 +94,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->getPaste(Helper::getPasteId())->delete();
|
||||
$paste = $this->_model->getPaste(Helper::getPasteId());
|
||||
$this->assertFalse($paste->exists(), 'paste successfully deleted');
|
||||
$this->assertEquals(array(), $paste->getComments(), 'comment was deleted with paste');
|
||||
$this->assertEquals([], $paste->getComments(), 'comment was deleted with paste');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,18 +232,18 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function testPurge()
|
||||
{
|
||||
$conf = new Configuration;
|
||||
$conf = new Configuration();
|
||||
$store = Database::getInstance($conf->getSection('model_options'));
|
||||
$store->delete(Helper::getPasteId());
|
||||
$expired = Helper::getPaste(array('expire_date' => 1344803344));
|
||||
$paste = Helper::getPaste(array('expire_date' => time() + 3600));
|
||||
$keys = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'x', 'y', 'z');
|
||||
$ids = array();
|
||||
$expired = Helper::getPaste(['expire_date' => 1344803344]);
|
||||
$paste = Helper::getPaste(['expire_date' => time() + 3600]);
|
||||
$keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'x', 'y', 'z'];
|
||||
$ids = [];
|
||||
foreach ($keys as $key) {
|
||||
$ids[$key] = substr(md5($key), 0, 16);
|
||||
$store->delete($ids[$key]);
|
||||
$this->assertFalse($store->exists($ids[$key]), "paste $key does not yet exist");
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
if (in_array($key, ['x', 'y', 'z'])) {
|
||||
$this->assertTrue($store->create($ids[$key], $paste), "store $key paste");
|
||||
} else {
|
||||
$this->assertTrue($store->create($ids[$key], $expired), "store $key paste");
|
||||
@ -250,7 +252,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
$this->_model->purge(10);
|
||||
foreach ($ids as $key => $id) {
|
||||
if (in_array($key, array('x', 'y', 'z'))) {
|
||||
if (in_array($key, ['x', 'y', 'z'])) {
|
||||
$this->assertTrue($this->_model->getPaste($id)->exists(), "paste $key exists after purge");
|
||||
$this->_model->getPaste($id)->delete();
|
||||
} else {
|
||||
@ -263,18 +265,18 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['main']['icon'] = 'none';
|
||||
$options['model'] = array(
|
||||
$options['model'] = [
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
];
|
||||
$options['model_options'] = [
|
||||
'dsn' => 'sqlite::memory:',
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
];
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$model = new Model(new Configuration);
|
||||
$model = new Model(new Configuration());
|
||||
|
||||
$pasteData = Helper::getPaste();
|
||||
$this->_model->getPaste(Helper::getPasteId())->delete();
|
||||
@ -291,7 +293,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($paste->exists(), 'paste exists after storing it');
|
||||
$paste = $paste->get();
|
||||
$this->assertEquals($pasteData['data'], $paste->data);
|
||||
foreach (array('opendiscussion', 'formatter') as $key) {
|
||||
foreach (['opendiscussion', 'formatter'] as $key) {
|
||||
$this->assertEquals($pasteData['meta'][$key], $paste->meta->$key);
|
||||
}
|
||||
|
||||
@ -318,18 +320,18 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['main']['icon'] = 'identicon';
|
||||
$options['model'] = array(
|
||||
$options['model'] = [
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
];
|
||||
$options['model_options'] = [
|
||||
'dsn' => 'sqlite::memory:',
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
];
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$model = new Model(new Configuration);
|
||||
$model = new Model(new Configuration());
|
||||
|
||||
$pasteData = Helper::getPaste();
|
||||
$commentData = Helper::getComment();
|
||||
@ -356,18 +358,18 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['main']['icon'] = 'vizhash';
|
||||
$options['model'] = array(
|
||||
$options['model'] = [
|
||||
'class' => 'Database',
|
||||
);
|
||||
$options['model_options'] = array(
|
||||
];
|
||||
$options['model_options'] = [
|
||||
'dsn' => 'sqlite::memory:',
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
|
||||
);
|
||||
'opt' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],
|
||||
];
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$model = new Model(new Configuration);
|
||||
$model = new Model(new Configuration());
|
||||
|
||||
$pasteData = Helper::getPaste();
|
||||
$commentData = Helper::getComment();
|
||||
@ -385,7 +387,7 @@ class ModelTest extends PHPUnit_Framework_TestCase
|
||||
$comment->store();
|
||||
|
||||
$vz = new Vizhash16x16();
|
||||
$pngdata = 'data:image/png;base64,' . base64_encode($vz->generate(TrafficLimiter::getHash()));
|
||||
$pngdata = 'data:image/png;base64,'.base64_encode($vz->generate(TrafficLimiter::getHash()));
|
||||
$comment = $paste->getComment(Helper::getPasteId(), Helper::getCommentId())->get();
|
||||
$this->assertEquals($pngdata, $comment->meta->vizhash, 'nickname triggers vizhash to be set');
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ class PurgeLimiterTest extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$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)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
|
@ -15,19 +15,19 @@ class ServerSaltTest extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$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)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
ServerSalt::setPath($this->_path);
|
||||
|
||||
$this->_otherPath = $this->_path . DIRECTORY_SEPARATOR . 'foo';
|
||||
$this->_otherPath = $this->_path.DIRECTORY_SEPARATOR.'foo';
|
||||
|
||||
$this->_invalidPath = $this->_path . DIRECTORY_SEPARATOR . 'bar';
|
||||
$this->_invalidPath = $this->_path.DIRECTORY_SEPARATOR.'bar';
|
||||
if (!is_dir($this->_invalidPath)) {
|
||||
mkdir($this->_invalidPath);
|
||||
}
|
||||
$this->_invalidFile = $this->_invalidPath . DIRECTORY_SEPARATOR . 'salt.php';
|
||||
$this->_invalidFile = $this->_invalidPath.DIRECTORY_SEPARATOR.'salt.php';
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
@ -88,7 +88,7 @@ class ServerSaltTest extends PHPUnit_Framework_TestCase
|
||||
chmod($this->_invalidFile, 0600);
|
||||
unlink($this->_invalidFile);
|
||||
}
|
||||
file_put_contents($this->_invalidPath . DIRECTORY_SEPARATOR . '.htaccess', '');
|
||||
file_put_contents($this->_invalidPath.DIRECTORY_SEPARATOR.'.htaccess', '');
|
||||
chmod($this->_invalidPath, 0500);
|
||||
ServerSalt::setPath($this->_invalidPath);
|
||||
ServerSalt::get();
|
||||
@ -102,7 +102,7 @@ class ServerSaltTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
// try creating an invalid path
|
||||
chmod($this->_invalidPath, 0000);
|
||||
ServerSalt::setPath($this->_invalidPath . DIRECTORY_SEPARATOR . 'baz');
|
||||
ServerSalt::setPath($this->_invalidPath.DIRECTORY_SEPARATOR.'baz');
|
||||
ServerSalt::get();
|
||||
}
|
||||
}
|
||||
|
@ -9,21 +9,21 @@ class TrafficLimiterTest extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'trafficlimit';
|
||||
$this->_path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'trafficlimit';
|
||||
TrafficLimiter::setPath($this->_path);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
/* Tear Down Routine */
|
||||
Helper::rmDir($this->_path . DIRECTORY_SEPARATOR);
|
||||
Helper::rmDir($this->_path.DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public function testTrafficGetsLimited()
|
||||
{
|
||||
$this->assertEquals($this->_path, TrafficLimiter::getPath());
|
||||
$file = 'baz';
|
||||
$this->assertEquals($this->_path . DIRECTORY_SEPARATOR . $file, TrafficLimiter::getPath($file));
|
||||
$this->assertEquals($this->_path.DIRECTORY_SEPARATOR.$file, TrafficLimiter::getPath($file));
|
||||
TrafficLimiter::setLimit(4);
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
$this->assertTrue(TrafficLimiter::canPass(), 'first request may pass');
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?php
|
||||
|
||||
use PrivateBin\Data\Filesystem;
|
||||
use PrivateBin\PrivateBin;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
use PrivateBin\PrivateBin;
|
||||
|
||||
class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -14,8 +14,8 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(array('dir' => $this->_path));
|
||||
$this->_path = sys_get_temp_dir().DIRECTORY_SEPARATOR.'privatebin_data';
|
||||
$this->_model = Filesystem::getInstance(['dir' => $this->_path]);
|
||||
ServerSalt::setPath($this->_path);
|
||||
$this->reset();
|
||||
}
|
||||
@ -29,9 +29,9 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$_POST = array();
|
||||
$_GET = array();
|
||||
$_SERVER = array();
|
||||
$_POST = [];
|
||||
$_GET = [];
|
||||
$_SERVER = [];
|
||||
if ($this->_model->exists(Helper::getPasteId())) {
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
}
|
||||
@ -51,7 +51,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->reset();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertContains(
|
||||
@ -78,7 +78,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$_COOKIE['lang'] = 'de';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertContains(
|
||||
@ -101,7 +101,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$_COOKIE['lang'] = 'de';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertContains(
|
||||
@ -124,11 +124,11 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$_COOKIE['lang'] = 'de';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
'#id="shortenbutton"[^>]*data-shortener="' . preg_quote($shortener) . '"#',
|
||||
'#id="shortenbutton"[^>]*data-shortener="'.preg_quote($shortener).'"#',
|
||||
$content,
|
||||
'outputs configured shortener URL correctly'
|
||||
);
|
||||
@ -140,16 +140,16 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
public function testHtaccess()
|
||||
{
|
||||
$this->reset();
|
||||
$dirs = array('cfg', 'lib');
|
||||
$dirs = ['cfg', 'lib'];
|
||||
foreach ($dirs as $dir) {
|
||||
$file = PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess';
|
||||
$file = PATH.$dir.DIRECTORY_SEPARATOR.'.htaccess';
|
||||
@unlink($file);
|
||||
}
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
ob_end_clean();
|
||||
foreach ($dirs as $dir) {
|
||||
$file = PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess';
|
||||
$file = PATH.$dir.DIRECTORY_SEPARATOR.'.htaccess';
|
||||
$this->assertFileExists(
|
||||
$file,
|
||||
"$dir htaccess recreated"
|
||||
@ -166,7 +166,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$this->reset();
|
||||
Helper::confBackup();
|
||||
file_put_contents(CONF, '');
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,7 +184,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -208,13 +208,13 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$options['traffic']['limit'] = 0;
|
||||
Helper::confBackup();
|
||||
Helper::createIniFile(CONF, $options);
|
||||
$_POST = Helper::getPaste(array('expire' => 25));
|
||||
$_POST = Helper::getPaste(['expire' => 25]);
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
TrafficLimiter::canPass();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -244,7 +244,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -268,7 +268,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -298,7 +298,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -324,7 +324,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$time = time();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -357,7 +357,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$time = time();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -389,7 +389,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -419,7 +419,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -443,7 +443,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -468,7 +468,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not exists before posting data');
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -476,7 +476,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
|
||||
$original = json_decode(json_encode($_POST));
|
||||
$stored = $this->_model->read($response['id']);
|
||||
foreach (array('data', 'attachment', 'attachmentname') as $key) {
|
||||
foreach (['data', 'attachment', 'attachmentname'] as $key) {
|
||||
$this->assertEquals($original->$key, $stored->$key);
|
||||
}
|
||||
$this->assertEquals(
|
||||
@ -488,7 +488,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* In some webserver setups (found with Suhosin) overly long POST params are
|
||||
* silently removed, check that this case is handled
|
||||
* silently removed, check that this case is handled.
|
||||
*
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
@ -507,7 +507,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not exists before posting data');
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -526,11 +526,11 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
ob_end_clean();
|
||||
$this->_model->delete(Helper::getPasteId());
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -554,7 +554,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -587,7 +587,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -613,7 +613,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -639,7 +639,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -663,10 +663,10 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
$paste = Helper::getPaste(array('opendiscussion' => false));
|
||||
$paste = Helper::getPaste(['opendiscussion' => false]);
|
||||
$this->_model->create(Helper::getPasteId(), $paste);
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -691,7 +691,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -719,7 +719,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -736,12 +736,12 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), Helper::getPaste());
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertContains(
|
||||
'<div id="cipherdata" class="hidden">' .
|
||||
htmlspecialchars(Helper::getPasteAsJson(), ENT_NOQUOTES) .
|
||||
'<div id="cipherdata" class="hidden">'.
|
||||
htmlspecialchars(Helper::getPasteAsJson(), ENT_NOQUOTES).
|
||||
'</div>',
|
||||
$content,
|
||||
'outputs data correctly'
|
||||
@ -756,7 +756,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$this->reset();
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -774,7 +774,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$this->reset();
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -790,11 +790,11 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
public function testReadExpired()
|
||||
{
|
||||
$this->reset();
|
||||
$expiredPaste = Helper::getPaste(array('expire_date' => 1344803344));
|
||||
$expiredPaste = Helper::getPaste(['expire_date' => 1344803344]);
|
||||
$this->_model->create(Helper::getPasteId(), $expiredPaste);
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -810,17 +810,17 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
public function testReadBurn()
|
||||
{
|
||||
$this->reset();
|
||||
$burnPaste = Helper::getPaste(array('burnafterreading' => true));
|
||||
$burnPaste = Helper::getPaste(['burnafterreading' => true]);
|
||||
$this->_model->create(Helper::getPasteId(), $burnPaste);
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
unset($burnPaste['meta']['salt']);
|
||||
$this->assertContains(
|
||||
'<div id="cipherdata" class="hidden">' .
|
||||
htmlspecialchars(Helper::getPasteAsJson($burnPaste['meta']), ENT_NOQUOTES) .
|
||||
'<div id="cipherdata" class="hidden">'.
|
||||
htmlspecialchars(Helper::getPasteAsJson($burnPaste['meta']), ENT_NOQUOTES).
|
||||
'</div>',
|
||||
$content,
|
||||
'outputs data correctly'
|
||||
@ -838,13 +838,13 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
$this->assertEquals(0, $response['status'], 'outputs success status');
|
||||
$this->assertEquals(Helper::getPasteId(), $response['id'], 'outputs data correctly');
|
||||
$this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertStringEndsWith('?'.$response['id'], $response['url'], 'returned URL points to new paste');
|
||||
$this->assertEquals($paste['data'], $response['data'], 'outputs data correctly');
|
||||
$this->assertEquals($paste['meta']['formatter'], $response['meta']['formatter'], 'outputs format correctly');
|
||||
$this->assertEquals($paste['meta']['postdate'], $response['meta']['postdate'], 'outputs postdate correctly');
|
||||
@ -862,7 +862,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -876,22 +876,22 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->reset();
|
||||
$oldPaste = Helper::getPaste();
|
||||
$meta = array(
|
||||
$meta = [
|
||||
'syntaxcoloring' => true,
|
||||
'postdate' => $oldPaste['meta']['postdate'],
|
||||
'postdate' => $oldPaste['meta']['postdate'],
|
||||
'opendiscussion' => $oldPaste['meta']['opendiscussion'],
|
||||
);
|
||||
];
|
||||
$oldPaste['meta'] = $meta;
|
||||
$this->_model->create(Helper::getPasteId(), $oldPaste);
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$meta['formatter'] = 'syntaxhighlighting';
|
||||
$this->assertContains(
|
||||
'<div id="cipherdata" class="hidden">' .
|
||||
htmlspecialchars(Helper::getPasteAsJson($meta), ENT_NOQUOTES) .
|
||||
'<div id="cipherdata" class="hidden">'.
|
||||
htmlspecialchars(Helper::getPasteAsJson($meta), ENT_NOQUOTES).
|
||||
'</div>',
|
||||
$content,
|
||||
'outputs data correctly'
|
||||
@ -909,14 +909,14 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$this->_model->create(Helper::getPasteId(), $oldPaste);
|
||||
$_SERVER['QUERY_STRING'] = Helper::getPasteId();
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$oldPaste['meta']['formatter'] = 'plaintext';
|
||||
unset($oldPaste['meta']['salt']);
|
||||
$this->assertContains(
|
||||
'<div id="cipherdata" class="hidden">' .
|
||||
htmlspecialchars(Helper::getPasteAsJson($oldPaste['meta']), ENT_NOQUOTES) .
|
||||
'<div id="cipherdata" class="hidden">'.
|
||||
htmlspecialchars(Helper::getPasteAsJson($oldPaste['meta']), ENT_NOQUOTES).
|
||||
'</div>',
|
||||
$content,
|
||||
'outputs data correctly'
|
||||
@ -935,7 +935,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_GET['pasteid'] = Helper::getPasteId();
|
||||
$_GET['deletetoken'] = hash_hmac('sha256', Helper::getPasteId(), $paste->meta->salt);
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -956,7 +956,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_GET['pasteid'] = 'foo';
|
||||
$_GET['deletetoken'] = 'bar';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -976,7 +976,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_GET['pasteid'] = Helper::getPasteId();
|
||||
$_GET['deletetoken'] = 'bar';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -996,7 +996,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_GET['pasteid'] = Helper::getPasteId();
|
||||
$_GET['deletetoken'] = 'bar';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -1013,7 +1013,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
public function testDeleteBurnAfterReading()
|
||||
{
|
||||
$this->reset();
|
||||
$burnPaste = Helper::getPaste(array('burnafterreading' => true));
|
||||
$burnPaste = Helper::getPaste(['burnafterreading' => true]);
|
||||
$this->_model->create(Helper::getPasteId(), $burnPaste);
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||
$_POST['deletetoken'] = 'burnafterreading';
|
||||
@ -1021,7 +1021,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -1042,7 +1042,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$response = json_decode($content, true);
|
||||
@ -1056,14 +1056,14 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
public function testDeleteExpired()
|
||||
{
|
||||
$this->reset();
|
||||
$expiredPaste = Helper::getPaste(array('expire_date' => 1000));
|
||||
$expiredPaste = Helper::getPaste(['expire_date' => 1000]);
|
||||
$this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not exist before being created');
|
||||
$this->_model->create(Helper::getPasteId(), $expiredPaste);
|
||||
$this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists before deleting data');
|
||||
$_GET['pasteid'] = Helper::getPasteId();
|
||||
$_GET['deletetoken'] = 'does not matter in this context, but has to be set';
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
@ -1087,7 +1087,7 @@ class PrivateBinTest extends PHPUnit_Framework_TestCase
|
||||
$_GET['pasteid'] = Helper::getPasteId();
|
||||
$_GET['deletetoken'] = hash_hmac('sha256', Helper::getPasteId(), ServerSalt::get());
|
||||
ob_start();
|
||||
new PrivateBin;
|
||||
new PrivateBin();
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertRegExp(
|
||||
|
@ -1,32 +1,30 @@
|
||||
<?php
|
||||
|
||||
use PrivateBin\Data\Database;
|
||||
use PrivateBin\PrivateBin;
|
||||
use PrivateBin\Persistence\ServerSalt;
|
||||
use PrivateBin\Persistence\TrafficLimiter;
|
||||
|
||||
require_once 'PrivateBinTest.php';
|
||||
|
||||
class PrivateBinWithDbTest extends PrivateBinTest
|
||||
{
|
||||
private $_options = array(
|
||||
private $_options = [
|
||||
'usr' => null,
|
||||
'pwd' => null,
|
||||
'opt' => array(
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_PERSISTENT => true
|
||||
),
|
||||
);
|
||||
'opt' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
],
|
||||
];
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$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)) {
|
||||
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->reset();
|
||||
}
|
||||
@ -36,9 +34,9 @@ class PrivateBinWithDbTest extends PrivateBinTest
|
||||
parent::reset();
|
||||
// but then inject a db config
|
||||
$options = parse_ini_file(CONF, true);
|
||||
$options['model'] = array(
|
||||
$options['model'] = [
|
||||
'class' => 'Database',
|
||||
);
|
||||
];
|
||||
$options['purge']['dir'] = $this->_path;
|
||||
$options['traffic']['dir'] = $this->_path;
|
||||
$options['model_options'] = $this->_options;
|
||||
|
@ -16,16 +16,16 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$_SERVER = array();
|
||||
$_GET = array();
|
||||
$_POST = array();
|
||||
$_SERVER = [];
|
||||
$_GET = [];
|
||||
$_POST = [];
|
||||
}
|
||||
|
||||
public function testView()
|
||||
{
|
||||
$this->reset();
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||
$this->assertEquals('view', $request->getOperation());
|
||||
}
|
||||
@ -35,7 +35,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$this->reset();
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
$this->assertEquals('read', $request->getOperation());
|
||||
@ -47,7 +47,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_GET['pasteid'] = 'foo';
|
||||
$_GET['deletetoken'] = 'bar';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||
$this->assertEquals('delete', $request->getOperation());
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
@ -62,7 +62,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
||||
file_put_contents($file, 'data=foo');
|
||||
Request::setInputStream($file);
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
||||
$this->assertEquals('create', $request->getOperation());
|
||||
$this->assertEquals('foo', $request->getParam('data'));
|
||||
@ -74,7 +74,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, */*; q=0.01';
|
||||
$_POST['attachment'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
||||
$this->assertEquals('create', $request->getOperation());
|
||||
$this->assertEquals('foo', $request->getParam('attachment'));
|
||||
@ -86,7 +86,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, */*; q=0.01';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
$this->assertEquals('read', $request->getOperation());
|
||||
@ -99,7 +99,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$_POST['deletetoken'] = 'bar';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
||||
$this->assertEquals('delete', $request->getOperation());
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
@ -112,7 +112,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['HTTP_ACCEPT'] = 'text/html,text/html; charset=UTF-8,application/xhtml+xml, application/xml;q=0.9,*/*;q=0.8, text/csv,application/json';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
$this->assertEquals('read', $request->getOperation());
|
||||
@ -124,7 +124,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['HTTP_ACCEPT'] = 'application/xhtml+xml,text/html,text/html; charset=UTF-8, application/xml;q=0.9,*/*;q=0.8, text/csv,application/json';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
$this->assertEquals('read', $request->getOperation());
|
||||
@ -136,7 +136,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['HTTP_ACCEPT'] = 'text/plain,text/csv, application/xml;q=0.9, application/json, text/html,text/html; charset=UTF-8,application/xhtml+xml, */*;q=0.8';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
$this->assertEquals('read', $request->getOperation());
|
||||
@ -148,7 +148,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['HTTP_ACCEPT'] = 'text/plain,text/csv, application/xml;q=0.9, */*;q=0.8';
|
||||
$_SERVER['QUERY_STRING'] = 'foo';
|
||||
$request = new Request;
|
||||
$request = new Request();
|
||||
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||
$this->assertEquals('foo', $request->getParam('pasteid'));
|
||||
$this->assertEquals('read', $request->getOperation());
|
||||
|
@ -9,19 +9,19 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
private static $status = '!*#@?$+';
|
||||
|
||||
private static $formatters = array(
|
||||
'plaintext' => 'Plain Text',
|
||||
private static $formatters = [
|
||||
'plaintext' => 'Plain Text',
|
||||
'syntaxhighlighting' => 'Source Code',
|
||||
'markdown' => 'Markdown',
|
||||
);
|
||||
'markdown' => 'Markdown',
|
||||
];
|
||||
|
||||
private static $formatter_default = 'plaintext';
|
||||
|
||||
private static $expire = array(
|
||||
'5min' => '5 minutes',
|
||||
private static $expire = [
|
||||
'5min' => '5 minutes',
|
||||
'1hour' => '1 hour',
|
||||
'never' => 'Never',
|
||||
);
|
||||
];
|
||||
|
||||
private static $expire_default = '1hour';
|
||||
|
||||
@ -32,7 +32,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$page = new View;
|
||||
$page = new View();
|
||||
$page->assign('CIPHERDATA', Helper::getPaste()['data']);
|
||||
$page->assign('ERROR', self::$error);
|
||||
$page->assign('STATUS', self::$status);
|
||||
@ -69,14 +69,14 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||
public function testTemplateRendersCorrectly()
|
||||
{
|
||||
$this->assertContains(
|
||||
'<div id="cipherdata" class="hidden">' .
|
||||
htmlspecialchars(Helper::getPaste()['data'], ENT_NOQUOTES) .
|
||||
'<div id="cipherdata" class="hidden">'.
|
||||
htmlspecialchars(Helper::getPaste()['data'], ENT_NOQUOTES).
|
||||
'</div>',
|
||||
$this->_content,
|
||||
'outputs data correctly'
|
||||
);
|
||||
$this->assertRegExp(
|
||||
'#<div[^>]+id="errormessage"[^>]*>.*' . self::$error . '</div>#',
|
||||
'#<div[^>]+id="errormessage"[^>]*>.*'.self::$error.'</div>#',
|
||||
$this->_content,
|
||||
'outputs error correctly'
|
||||
);
|
||||
@ -97,7 +97,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||
);
|
||||
// testing version number in JS address, since other instances may not be present in different templates
|
||||
$this->assertRegExp(
|
||||
'#<script[^>]+src="js/privatebin.js\\?' . rawurlencode(self::$version) . '"[^>]*>#',
|
||||
'#<script[^>]+src="js/privatebin.js\\?'.rawurlencode(self::$version).'"[^>]*>#',
|
||||
$this->_content,
|
||||
'outputs version correctly'
|
||||
);
|
||||
@ -109,7 +109,7 @@ class ViewTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testMissingTemplate()
|
||||
{
|
||||
$test = new View;
|
||||
$test = new View();
|
||||
$test->draw('123456789 does not exist!');
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,11 @@ class Vizhash16x16Test extends PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
/* Setup Routine */
|
||||
$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)) {
|
||||
mkdir($this->_path);
|
||||
}
|
||||
$this->_file = $this->_path . DIRECTORY_SEPARATOR . 'vizhash.png';
|
||||
$this->_file = $this->_path.DIRECTORY_SEPARATOR.'vizhash.png';
|
||||
ServerSalt::setPath($this->_path);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user