Merge branch 'master' into php8
This commit is contained in:
commit
6d116e0cd9
@ -1,5 +1,9 @@
|
|||||||
# PrivateBin version history
|
# PrivateBin version history
|
||||||
|
|
||||||
|
* **1.5.1 (not yet released)**
|
||||||
|
* FIXED: Revert Filesystem purge to limited and randomized lookup (#1030)
|
||||||
|
* FIXED: Catch JSON decode errors when invalid data gets sent to the API (#1030)
|
||||||
|
* FIXED: Support sorting v1 format in mixed version comments in Filesystem backend (#1030)
|
||||||
* **1.5 (2022-12-11)**
|
* **1.5 (2022-12-11)**
|
||||||
* ADDED: script for data storage backend migrations (#1012)
|
* ADDED: script for data storage backend migrations (#1012)
|
||||||
* ADDED: Translations for Turkish, Slovak, Greek and Thai
|
* ADDED: Translations for Turkish, Slovak, Greek and Thai
|
||||||
|
@ -29,9 +29,8 @@
|
|||||||
* rodehoed - option to exempt ips from the rate-limiter
|
* rodehoed - option to exempt ips from the rate-limiter
|
||||||
* Mark van Holsteijn - Google Cloud Storage backend
|
* Mark van Holsteijn - Google Cloud Storage backend
|
||||||
* Austin Huang - Oracle database support
|
* Austin Huang - Oracle database support
|
||||||
* Felix J. Ogris - S3 Storage backend
|
* Felix J. Ogris - S3 Storage backend, script for data backend migrations, dropped singleton behaviour of data backends
|
||||||
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
|
* Mounir Idrassi & J. Mozdzen - secure YOURLS integration
|
||||||
* Felix J. Ogris - script for data backend migrations, dropped singleton behaviour of data backends
|
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
* Hexalyse - French
|
* Hexalyse - French
|
||||||
|
@ -228,7 +228,13 @@ class Filesystem extends AbstractData
|
|||||||
$comment['parentid'] = $items[2];
|
$comment['parentid'] = $items[2];
|
||||||
|
|
||||||
// Store in array
|
// Store in array
|
||||||
$key = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
|
$key = $this->getOpenSlot(
|
||||||
|
$comments, (
|
||||||
|
(int) array_key_exists('created', $comment['meta']) ?
|
||||||
|
$comment['meta']['created'] : // v2 comments
|
||||||
|
$comment['meta']['postdate'] // v1 comments
|
||||||
|
)
|
||||||
|
);
|
||||||
$comments[$key] = $comment;
|
$comments[$key] = $comment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,12 +364,12 @@ class Filesystem extends AbstractData
|
|||||||
{
|
{
|
||||||
$pastes = array();
|
$pastes = array();
|
||||||
$count = 0;
|
$count = 0;
|
||||||
|
$opened = 0;
|
||||||
|
$limit = $batchsize * 10; // try at most 10 times $batchsize pastes before giving up
|
||||||
$time = time();
|
$time = time();
|
||||||
foreach ($this->_getPasteIterator() as $file) {
|
$files = $this->getAllPastes();
|
||||||
if ($file->isDir()) {
|
shuffle($files);
|
||||||
continue;
|
foreach ($files as $pasteid) {
|
||||||
}
|
|
||||||
$pasteid = $file->getBasename('.php');
|
|
||||||
if ($this->exists($pasteid)) {
|
if ($this->exists($pasteid)) {
|
||||||
$data = $this->read($pasteid);
|
$data = $this->read($pasteid);
|
||||||
if (
|
if (
|
||||||
@ -371,11 +377,13 @@ class Filesystem extends AbstractData
|
|||||||
$data['meta']['expire_date'] < $time
|
$data['meta']['expire_date'] < $time
|
||||||
) {
|
) {
|
||||||
$pastes[] = $pasteid;
|
$pastes[] = $pasteid;
|
||||||
++$count;
|
if (++$count >= $batchsize) {
|
||||||
if ($count >= $batchsize) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (++$opened >= $limit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $pastes;
|
return $pastes;
|
||||||
@ -387,7 +395,7 @@ class Filesystem extends AbstractData
|
|||||||
public function getAllPastes()
|
public function getAllPastes()
|
||||||
{
|
{
|
||||||
$pastes = array();
|
$pastes = array();
|
||||||
foreach ($this->_getPasteIterator() as $file) {
|
foreach (new \GlobIterator($this->_path . self::PASTE_FILE_PATTERN) as $file) {
|
||||||
if ($file->isFile()) {
|
if ($file->isFile()) {
|
||||||
$pastes[] = $file->getBasename('.php');
|
$pastes[] = $file->getBasename('.php');
|
||||||
}
|
}
|
||||||
@ -431,20 +439,6 @@ class Filesystem extends AbstractData
|
|||||||
'.discussion' . DIRECTORY_SEPARATOR;
|
'.discussion' . DIRECTORY_SEPARATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an iterator matching paste files.
|
|
||||||
*
|
|
||||||
* Note that creating the iterator issues the glob() call, so we can't pre-
|
|
||||||
* generate this object before files that should get matched exist.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
* @return \GlobIterator
|
|
||||||
*/
|
|
||||||
private function _getPasteIterator()
|
|
||||||
{
|
|
||||||
return new \GlobIterator($this->_path . self::PASTE_FILE_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* store the data
|
* store the data
|
||||||
*
|
*
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
namespace PrivateBin;
|
namespace PrivateBin;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request
|
* Request
|
||||||
*
|
*
|
||||||
@ -110,9 +112,13 @@ class Request
|
|||||||
case 'POST':
|
case 'POST':
|
||||||
// it might be a creation or a deletion, the latter is detected below
|
// it might be a creation or a deletion, the latter is detected below
|
||||||
$this->_operation = 'create';
|
$this->_operation = 'create';
|
||||||
|
try {
|
||||||
$this->_params = Json::decode(
|
$this->_params = Json::decode(
|
||||||
file_get_contents(self::$_inputStream)
|
file_get_contents(self::$_inputStream)
|
||||||
);
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// ignore error, $this->_params will remain empty
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->_params = $_GET;
|
$this->_params = $_GET;
|
||||||
|
@ -149,7 +149,7 @@ class BucketStub extends Bucket
|
|||||||
throw new BadMethodCallException('not supported by this stub');
|
throw new BadMethodCallException('not supported by this stub');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exists()
|
public function exists(array $options = array())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -450,9 +450,12 @@ class ControllerTest extends TestCase
|
|||||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||||
$_SERVER['REMOTE_ADDR'] = '::1';
|
$_SERVER['REMOTE_ADDR'] = '::1';
|
||||||
$this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste does not exists before posting data');
|
$this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste does not exists before posting data');
|
||||||
$this->expectException(Exception::class);
|
ob_start();
|
||||||
$this->expectExceptionCode(90);
|
|
||||||
new Controller;
|
new Controller;
|
||||||
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
$response = json_decode($content, true);
|
||||||
|
$this->assertEquals(1, $response['status'], 'outputs error status');
|
||||||
$this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste exists after posting data');
|
$this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste exists after posting data');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class RequestTest extends TestCase
|
|||||||
Request::setInputStream($file);
|
Request::setInputStream($file);
|
||||||
$request = new Request;
|
$request = new Request;
|
||||||
unlink($file);
|
unlink($file);
|
||||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
$this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
|
||||||
$this->assertEquals('create', $request->getOperation());
|
$this->assertEquals('create', $request->getOperation());
|
||||||
$this->assertEquals('foo', $request->getParam('ct'));
|
$this->assertEquals('foo', $request->getParam('ct'));
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ class RequestTest extends TestCase
|
|||||||
file_put_contents($file, '{"ct":"foo"}');
|
file_put_contents($file, '{"ct":"foo"}');
|
||||||
Request::setInputStream($file);
|
Request::setInputStream($file);
|
||||||
$request = new Request;
|
$request = new Request;
|
||||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
$this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
|
||||||
$this->assertEquals('create', $request->getOperation());
|
$this->assertEquals('create', $request->getOperation());
|
||||||
$this->assertEquals('foo', $request->getParam('ct'));
|
$this->assertEquals('foo', $request->getParam('ct'));
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ class RequestTest extends TestCase
|
|||||||
$_SERVER['QUERY_STRING'] = $id;
|
$_SERVER['QUERY_STRING'] = $id;
|
||||||
$_GET[$id] = '';
|
$_GET[$id] = '';
|
||||||
$request = new Request;
|
$request = new Request;
|
||||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
$this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
|
||||||
$this->assertEquals($id, $request->getParam('pasteid'));
|
$this->assertEquals($id, $request->getParam('pasteid'));
|
||||||
$this->assertEquals('read', $request->getOperation());
|
$this->assertEquals('read', $request->getOperation());
|
||||||
}
|
}
|
||||||
@ -133,12 +133,25 @@ class RequestTest extends TestCase
|
|||||||
file_put_contents($file, '{"deletetoken":"bar"}');
|
file_put_contents($file, '{"deletetoken":"bar"}');
|
||||||
Request::setInputStream($file);
|
Request::setInputStream($file);
|
||||||
$request = new Request;
|
$request = new Request;
|
||||||
$this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
|
$this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
|
||||||
$this->assertEquals('delete', $request->getOperation());
|
$this->assertEquals('delete', $request->getOperation());
|
||||||
$this->assertEquals($id, $request->getParam('pasteid'));
|
$this->assertEquals($id, $request->getParam('pasteid'));
|
||||||
$this->assertEquals('bar', $request->getParam('deletetoken'));
|
$this->assertEquals('bar', $request->getParam('deletetoken'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPostGarbage()
|
||||||
|
{
|
||||||
|
$this->reset();
|
||||||
|
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||||
|
$file = tempnam(sys_get_temp_dir(), 'FOO');
|
||||||
|
file_put_contents($file, random_bytes(256));
|
||||||
|
Request::setInputStream($file);
|
||||||
|
$request = new Request;
|
||||||
|
unlink($file);
|
||||||
|
$this->assertFalse($request->isJsonApiCall(), 'is HTML call');
|
||||||
|
$this->assertEquals('create', $request->getOperation());
|
||||||
|
}
|
||||||
|
|
||||||
public function testReadWithNegotiation()
|
public function testReadWithNegotiation()
|
||||||
{
|
{
|
||||||
$this->reset();
|
$this->reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user