Release v1.5.1

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEHCqJCvETXOw2gWZqD1yUCmvYH5IFAmOmjmMACgkQD1yUCmvY
 H5J2cBAA2GchTFearhcLAtUqYZ6fj8ZmVXy7paCtT/o5yhpj1Ll8e+wKWhuormut
 LBQV+j6LnnQ1CzIRYVpPWz4o562bMrBR6qey/NyZMiAUy/b00ENGKoj3V8HOEgZY
 MCcswuZQRJJowrwwFVb1HePbuCwKVjMSf5sXUs+H3duLVzfA6G8cRkhNB+mEd2Z5
 E1GdkI1P630+XHl/TNK+0Aef24zimaZP8BPLsDTQ/8klw4hKQPfQnpntCbaqnVfh
 xpsXxj8/crRGOlMnjwxBxuNW45Pb7p87i3EYRlGokN6hC847f+Q9ZzO7M2YcoVUA
 5QPTx8+gjG8pokS7nqqmLdh4dRmKue+ayFXfva9S313xehLsJRHRJ5iJJkeoz+C8
 48lqqwZ2kznzgYM3scVA0PSusOLjFcd35geV+4Em/qmD1ydvr+j85vc7xKfM33UP
 N0IkEG61GDl5VIzuFqvHRboH8Tg9T7GBlwVEvmXDUNkS/uLK/EmZRuyo6AeH5vP0
 RkaZ3eXKMnvcl5jY5qeRtNEOZUoYHZKkS8J8zIwgDfPsLBb+Y3BqnTxFNAJzfDEN
 f7P2Yq4v4MOprJWjiBjnapTFYxKX56NeZMyxbBHPLjrKSQBboyMD4osSBF9Jo9gK
 NRCknEkuS9QM0Fqhqy+1CXgQxPoYAlyMQuwnjVh8opHRX0zn784=
 =Qp9X
 -----END PGP SIGNATURE-----

Merge tag '1.5.1' into ctrlv.chalec.org-1.5.1

Release v1.5.1
This commit is contained in:
Adrien Bourmault 2023-03-28 11:54:06 +02:00 committed by root
commit 112a550417
46 changed files with 467 additions and 127 deletions

View File

@ -1,5 +1,10 @@
# PrivateBin version history # PrivateBin version history
* **1.5.1 (2022-12-24)**
* ADDED: script for administrative tasks: deleting pastes (#274), removing empty directories (#277), purging expired pastes (#276) & statistics (#319)
* 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

View File

@ -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

View File

@ -205,7 +205,7 @@ CREATE INDEX parent ON prefix_comment(pasteid);
CREATE TABLE prefix_config ( CREATE TABLE prefix_config (
id CHAR(16) NOT NULL, value TEXT, PRIMARY KEY (id) id CHAR(16) NOT NULL, value TEXT, PRIMARY KEY (id)
); );
INSERT INTO prefix_config VALUES('VERSION', '1.5.0'); INSERT INTO prefix_config VALUES('VERSION', '1.5.1');
``` ```
In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns

View File

@ -1,8 +1,8 @@
.PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help .PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help
CURRENT_VERSION = 1.5.0 CURRENT_VERSION = 1.5.1
VERSION ?= 1.5.1 VERSION ?= 1.5.2
VERSION_FILES = index.php cfg/ *.md css/ i18n/ img/ js/package.json js/privatebin.js lib/ Makefile tpl/ tst/ VERSION_FILES = index.php bin/ cfg/ *.md css/ i18n/ img/ js/package.json js/privatebin.js lib/ Makefile tpl/ tst/
REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g") REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g")
REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g") REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g")
@ -38,7 +38,7 @@ increment: ## Increment and commit new version number, set target version using
git commit -m "incrementing version" git commit -m "incrementing version"
sign: ## Sign a release. sign: ## Sign a release.
git tag $(VERSION) git tag --sign --message "Release v$(VERSION)" $(VERSION)
git push origin $(VERSION) git push origin $(VERSION)
signrelease.sh signrelease.sh

View File

@ -1,6 +1,6 @@
# [![PrivateBin](https://cdn.rawgit.com/PrivateBin/assets/master/images/preview/logoSmall.png)](https://privatebin.info/) # [![PrivateBin](https://cdn.rawgit.com/PrivateBin/assets/master/images/preview/logoSmall.png)](https://privatebin.info/)
*Current version: 1.5.0* *Current version: 1.5.1*
**PrivateBin** is a minimalist, open source online **PrivateBin** is a minimalist, open source online
[pastebin](https://en.wikipedia.org/wiki/Pastebin) [pastebin](https://en.wikipedia.org/wiki/Pastebin)

View File

@ -4,8 +4,8 @@
| Version | Supported | | Version | Supported |
| ------- | ------------------ | | ------- | ------------------ |
| 1.5.0 | :heavy_check_mark: | | 1.5.1 | :heavy_check_mark: |
| < 1.5.0 | :x: | | < 1.5.1 | :x: |
## Reporting a Vulnerability ## Reporting a Vulnerability

318
bin/administration Executable file
View File

@ -0,0 +1,318 @@
#!/usr/bin/env php
<?php
/**
* 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.5.1
*/
namespace PrivateBin;
use PrivateBin\Configuration;
use PrivateBin\Data\AbstractData;
use PrivateBin\Model\Paste;
define('PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
require PATH . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
/**
* Administration
*
* Command line utility for administrative tasks.
*/
class Administration
{
/**
* configuration
*
* @access private
* @var Configuration
*/
private $_conf;
/**
* options, parsed from the command line arguments
*
* @access private
* @var array
*/
private $_opts = array();
/**
* data storage model
*
* @access private
* @var AbstractData
*/
private $_store;
/**
* deletes the requested paste ID, if a valid ID and it exists
*
* @access private
* @param string $pasteId
*/
private function _delete($pasteId)
{
if (!Paste::isValidId($pasteId)) {
self::_error('given ID is not a valid paste ID (16 hexadecimal digits)', 5);
}
if (!$this->_store->exists($pasteId)) {
self::_error('given ID does not exist, has expired or was already deleted', 6);
}
$this->_store->delete($pasteId);
if ($this->_store->exists($pasteId)) {
self::_error('paste ID exists after deletion, permission problem?', 7);
}
exit("paste $pasteId successfully deleted" . PHP_EOL);
}
/**
* removes empty directories, if current storage model uses Filesystem
*
* @access private
*/
private function _empty_dirs()
{
if ($this->_conf->getKey('class', 'model') !== 'Filesystem') {
self::_error('instance not using Filesystem storage, no directories to empty', 4);
}
$dir = $this->_conf->getKey('dir', 'model_options');
passthru("find $dir -type d -empty -delete", $code);
exit($code);
}
/**
* display a message on STDERR and exits
*
* @access private
* @static
* @param string $message
* @param int $code optional, defaults to 1
*/
private static function _error($message, $code = 1)
{
self::_error_echo($message);
exit($code);
}
/**
* display a message on STDERR
*
* @access private
* @static
* @param string $message
*/
private static function _error_echo($message)
{
fwrite(STDERR, 'Error: ' . $message . PHP_EOL);
}
/**
* display usage help on STDOUT and exits
*
* @access private
* @static
* @param int $code optional, defaults to 0
*/
private static function _help($code = 0)
{
echo <<<'EOT'
Usage:
administration [--delete <paste id> | --empty-dirs | --help | --purge | --statistics]
Options:
-d, --delete deletes the requested paste ID
-e, --empty-dirs removes empty directories (only if Filesystem storage is
configured)
-h, --help displays this help message
-p, --purge purge all expired pastes
-s, --statistics reads all stored pastes and comments and reports statistics
EOT, PHP_EOL;
exit($code);
}
/**
* return option for given short or long keyname, if it got set
*
* @access private
* @static
* @param string $short
* @param string $long
* @return string|null
*/
private function _option($short, $long)
{
foreach (array($short, $long) as $key) {
if (array_key_exists($key, $this->_opts)) {
return $this->_opts[$key];
}
}
return null;
}
/**
* initialize options from given argument array
*
* @access private
* @static
* @param array $arguments
*/
private function _options_initialize($arguments)
{
if ($arguments > 3) {
self::_error_echo('too many arguments given');
echo PHP_EOL;
self::_help(1);
}
if ($arguments < 2) {
self::_error_echo('missing arguments');
echo PHP_EOL;
self::_help(2);
}
$this->_opts = getopt('hd:eps', array('help', 'delete:', 'empty-dirs', 'purge', 'statistics'));
if (!$this->_opts) {
self::_error_echo('unsupported arguments given');
echo PHP_EOL;
self::_help(3);
}
}
/**
* reads all stored pastes and comments and reports statistics
*
* @access public
*/
private function _statistics()
{
$counters = array(
'burn' => 0,
'discussion' => 0,
'expired' => 0,
'md' => 0,
'percent' => 1,
'plain' => 0,
'progress' => 0,
'syntax' => 0,
'total' => 0,
'unknown' => 0,
);
$time = time();
$ids = $this->_store->getAllPastes();
$counters['total'] = count($ids);
$dots = $counters['total'] < 100 ? 10 : (
$counters['total'] < 1000 ? 50 : 100
);
$percentages = $counters['total'] < 100 ? 0 : (
$counters['total'] < 1000 ? 4 : 10
);
echo "Total:\t\t\t${counters['total']}", PHP_EOL;
foreach ($ids as $pasteid) {
$paste = $this->_store->read($pasteid);
++$counters['progress'];
if (
array_key_exists('expire_date', $paste['meta']) &&
$paste['meta']['expire_date'] < $time
) {
++$counters['expired'];
}
if (array_key_exists('adata', $paste)) {
$format = $paste['adata'][1];
$discussion = $paste['adata'][2];
$burn = $paste['adata'][3];
} else {
$format = array_key_exists('formatter', $paste['meta']) ? $paste['meta']['formatter'] : 'plaintext';
$discussion = array_key_exists('opendiscussion', $paste['meta']) ? $paste['meta']['opendiscussion'] : false;
$burn = array_key_exists('burnafterreading', $paste['meta']) ? $paste['meta']['burnafterreading'] : false;
}
if ($format === 'plaintext') {
++$counters['plain'];
} elseif ($format === 'syntaxhighlighting') {
++$counters['syntax'];
} elseif ($format === 'markdown') {
++$counters['md'];
} else {
++$counters['unknown'];
}
$counters['discussion'] += (int) $discussion;
$counters['burn'] += (int) $burn;
// display progress
if ($counters['progress'] % $dots === 0) {
echo '.';
if ($percentages) {
$progress = $percentages / $counters['total'] * $counters['progress'];
if ($progress >= $counters['percent']) {
printf(' %d%% ', 100 / $percentages * $progress);
++$counters['percent'];
}
}
}
}
echo PHP_EOL, <<<EOT
Expired:\t\t${counters['expired']}
Burn after reading:\t${counters['burn']}
Discussions:\t\t${counters['discussion']}
Plain Text:\t\t${counters['plain']}
Source Code:\t\t${counters['syntax']}
Markdown:\t\t${counters['md']}
EOT, PHP_EOL;
if ($counters['unknown'] > 0) {
echo "Unknown format:\t\t${counters['unknown']}", PHP_EOL;
}
}
/**
* constructor
*
* initializes and runs administrative tasks
*
* @access public
*/
public function __construct()
{
$this->_options_initialize($_SERVER['argc']);
if ($this->_option('h', 'help') !== null) {
self::_help();
}
$this->_conf = new Configuration;
if ($this->_option('e', 'empty-dirs') !== null) {
$this->_empty_dirs();
}
$class = 'PrivateBin\\Data\\' . $this->_conf->getKey('class', 'model');
$this->_store = new $class($this->_conf->getSection('model_options'));
if (($pasteId = $this->_option('d', 'delete')) !== null) {
$this->_delete($pasteId);
}
if ($this->_option('p', 'purge') !== null) {
$this->_store->purge(PHP_INT_MAX);
exit('purging of expired pastes concluded' . PHP_EOL);
}
if ($this->_option('s', 'statistics') !== null) {
$this->_statistics();
}
}
}
new Administration();

View File

@ -17,13 +17,14 @@ if (version_compare(PHP_VERSION, '7.1.0') < 0) {
$longopts = array( $longopts = array(
"delete-after", "delete-after",
"delete-during" "delete-during",
"help"
); );
$opts_arr = getopt("fhnv", $longopts, $rest); $opts_arr = getopt("fhnv", $longopts, $rest);
if ($opts_arr === false) { if ($opts_arr === false) {
dieerr("Erroneous command line options. Please use -h"); dieerr("Erroneous command line options. Please use --help");
} }
if (array_key_exists("h", $opts_arr)) { if (array_key_exists("h", $opts_arr) || array_key_exists("help", $opts_arr)) {
helpexit(); helpexit();
} }
@ -173,12 +174,12 @@ function debug ($text) {
function helpexit () function helpexit ()
{ {
print("migrate.php - Copy data between PrivateBin backends print("migrate - Copy data between PrivateBin backends
Usage: Usage:
migrate [--delete-after] [--delete-during] [-f] [-n] [-v] srcconfdir migrate [--delete-after] [--delete-during] [-f] [-n] [-v] srcconfdir
[<dstconfdir>] [<dstconfdir>]
migrate [-h] migrate [-h|--help]
Options: Options:
--delete-after delete data from source after all pastes and comments have --delete-after delete data from source after all pastes and comments have
@ -187,6 +188,7 @@ Options:
comments have successfully been copied to the destination comments have successfully been copied to the destination
-f forcefully overwrite data which already exists at the -f forcefully overwrite data which already exists at the
destination destination
-h, --help displays this help message
-n dry run, do not copy data -n dry run, do not copy data
-v be verbose -v be verbose
<srcconfdir> use storage backend configration from conf.php found in <srcconfdir> use storage backend configration from conf.php found in

View File

@ -31,8 +31,8 @@
"jdenticon/jdenticon": "^1.0" "jdenticon/jdenticon": "^1.0"
}, },
"suggest" : { "suggest" : {
"google/cloud-storage" : "1.26.1", "google/cloud-storage" : "1.30.1",
"aws/aws-sdk-php" : "3.239.0" "aws/aws-sdk-php" : "3.254.0"
}, },
"require-dev" : { "require-dev" : {
"phpunit/phpunit" : "^4.6 || ^5.0" "phpunit/phpunit" : "^4.6 || ^5.0"

View File

@ -6,7 +6,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
body { body {

View File

@ -6,7 +6,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
/* When there is no script at all other */ /* When there is no script at all other */

View File

@ -6,7 +6,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
/* CSS Reset from YUI 3.4.1 (build 4118) - Copyright 2011 Yahoo! Inc. All rights reserved. /* CSS Reset from YUI 3.4.1 (build 4118) - Copyright 2011 Yahoo! Inc. All rights reserved.

View File

@ -47,7 +47,7 @@
"%d minutes (3rd plural)" "%d minutes (3rd plural)"
], ],
"%d hours": [ "%d hours": [
"%d hodin", "%d hodina",
"%d hodiny", "%d hodiny",
"%d hodin", "%d hodin",
"%d hours (3rd plural)" "%d hours (3rd plural)"

View File

@ -187,7 +187,7 @@
"URL shortener may expose your decrypt key in URL.": "URL trumpinimo įrankis gali atskleisti URL adrese jūsų iššifravimo raktą.", "URL shortener may expose your decrypt key in URL.": "URL trumpinimo įrankis gali atskleisti URL adrese jūsų iššifravimo raktą.",
"Save paste": "Įrašyti įdėjimą", "Save paste": "Įrašyti įdėjimą",
"Your IP is not authorized to create pastes.": "Jūsų IP adresas neturi įgaliojimų kurti įdėjimų.", "Your IP is not authorized to create pastes.": "Jūsų IP adresas neturi įgaliojimų kurti įdėjimų.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.", "Trying to shorten a URL that isn't pointing at our instance.": "Bandoma sutrumpinti URL adresą, kuris nenurodo į mūsų egzempliorių.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".", "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Klaida iškviečiant YOURLS. Tikriausiai, konfigūracijos klaida, pavyzdžiui, neteisingi „apiurl“ ar „signature“, arba jų nėra.",
"Error parsing YOURLS response.": "Error parsing YOURLS response." "Error parsing YOURLS response.": "Klaida nagrinėjant YOURLS atsaką."
} }

View File

@ -1,10 +1,10 @@
{ {
"PrivateBin": "PrivateBin", "PrivateBin": "PrivateBin",
"%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is een minimalistische, open source online pastebin waarbij de server geen kennis heeft van de geplakte gegevens. Gegevens worden gecodeerd/gedecodeerd %s in de browser %s met behulp van 256 bits AES.", "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is een minimalistische, open source online pastebin waarbij de server geen kennis heeft van de paste data zelf. Gegevens worden gecodeerd/gedecodeerd %s in de browser %s met behulp van 256-bits AES.",
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Meer informatie is te vinden op de <a href=\"https://privatebin.info/\">projectpagina</a>.", "More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Meer informatie is te vinden op de <a href=\"https://privatebin.info/\">projectpagina</a>.",
"Because ignorance is bliss": "Onwetendheid is een zegen", "Because ignorance is bliss": "Onwetendheid is een zegen",
"en": "nl", "en": "nl",
"Paste does not exist, has expired or has been deleted.": "Geplakte tekst bestaat niet, is verlopen of verwijderd.", "Paste does not exist, has expired or has been deleted.": "Paste bestaat niet, is verlopen of verwijderd.",
"%s requires php %s or above to work. Sorry.": "%s vereist PHP %s of hoger om te kunnen werken. Sorry", "%s requires php %s or above to work. Sorry.": "%s vereist PHP %s of hoger om te kunnen werken. Sorry",
"%s requires configuration section [%s] to be present in configuration file.": "%s vereist dat de configuratiesectie [%s] aanwezig is in het configuratiebestand", "%s requires configuration section [%s] to be present in configuration file.": "%s vereist dat de configuratiesectie [%s] aanwezig is in het configuratiebestand",
"Please wait %d seconds between each post.": [ "Please wait %d seconds between each post.": [
@ -13,20 +13,20 @@
"Alstublieft %d seconden wachten tussen elk bericht.", "Alstublieft %d seconden wachten tussen elk bericht.",
"Alstublieft %d seconden wachten tussen elk bericht." "Alstublieft %d seconden wachten tussen elk bericht."
], ],
"Paste is limited to %s of encrypted data.": "Geplakte tekst is beperkt tot %s aan versleutelde gegevens", "Paste is limited to %s of encrypted data.": "Paste is beperkt tot %s aan versleutelde gegevens.",
"Invalid data.": "Ongeldige gegevens", "Invalid data.": "Ongeldige gegevens.",
"You are unlucky. Try again.": "Helaas. Probeer het nog eens", "You are unlucky. Try again.": "Helaas. Probeer het nog eens.",
"Error saving comment. Sorry.": "Fout bij het opslaan van het commentaar. Sorry", "Error saving comment. Sorry.": "Fout bij het opslaan van het commentaar. Sorry",
"Error saving paste. Sorry.": "Fout bij het opslaan van de geplakte tekst. Sorry.", "Error saving paste. Sorry.": "Fout bij het opslaan van de paste. Sorry.",
"Invalid paste ID.": "Ongeldige ID.", "Invalid paste ID.": "Ongeldige ID.",
"Paste is not of burn-after-reading type.": "Geplakte tekst is geen 'vernietig na lezen' type", "Paste is not of burn-after-reading type.": "Paste is geen 'vernietig na lezen' type.",
"Wrong deletion token. Paste was not deleted.": "Foutieve verwijdercode. Geplakte tekst is niet verwijderd.", "Wrong deletion token. Paste was not deleted.": "Foutieve verwijdercode. Paste is niet verwijderd.",
"Paste was properly deleted.": "Geplakte tekst is correct verwijderd.", "Paste was properly deleted.": "Paste is correct verwijderd.",
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript vereist om %s te laten werken. Sorry voor het ongemak.", "JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript vereist om %s te laten werken. Sorry voor het ongemak.",
"%s requires a modern browser to work.": "%s vereist een moderne browser om te kunnen werken ", "%s requires a modern browser to work.": "%s vereist een moderne browser om te kunnen werken.",
"New": "Nieuw", "New": "Nieuw",
"Send": "Verzenden", "Send": "Verzenden",
"Clone": "Clonen", "Clone": "Klonen",
"Raw text": "Onbewerkte tekst", "Raw text": "Onbewerkte tekst",
"Expires": "Verloopt", "Expires": "Verloopt",
"Burn after reading": "Vernietig na lezen", "Burn after reading": "Vernietig na lezen",
@ -77,7 +77,7 @@
"%d years (3rd plural)" "%d years (3rd plural)"
], ],
"Never": "Nooit", "Never": "Nooit",
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Opmerking: Dit is een testservice: Gegevens kunnen op elk gegeven moment verwijderd worden.", "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Opmerking: Dit is een testservice: Gegevens kunnen op elk gegeven moment verwijderd worden. Katten zullen doodgaan als je misbruikt maakt van deze service.",
"This document will expire in %d seconds.": [ "This document will expire in %d seconds.": [
"Dit document verloopt over %d seconde.", "Dit document verloopt over %d seconde.",
"Dit document verloopt over %d seconden.", "Dit document verloopt over %d seconden.",
@ -108,14 +108,14 @@
"Dit document verloopt over %d maanden.", "Dit document verloopt over %d maanden.",
"Dit document verloopt over %d maanden." "Dit document verloopt over %d maanden."
], ],
"Please enter the password for this paste:": "Voer het wachtwoord in voor deze geplakte tekst:", "Please enter the password for this paste:": "Voer het wachtwoord in voor deze paste:",
"Could not decrypt data (Wrong key?)": "Kon de gegevens niet decoderen (verkeerde sleutel?)", "Could not decrypt data (Wrong key?)": "Kon de gegevens niet decoderen (verkeerde sleutel?)",
"Could not delete the paste, it was not stored in burn after reading mode.": "Verwijderen van de geplakte tekst niet mogelijk, deze werd niet opgeslagen in 'vernietig na lezen' modus.", "Could not delete the paste, it was not stored in burn after reading mode.": "Verwijderen van de paste niet mogelijk, deze werd niet opgeslagen in 'vernietig na lezen' modus.",
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Sluit dit venster niet, dit bericht kan niet opnieuw worden weergegeven.", "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "ALLEEN VOOR JOUW OGEN BESTEMD. Sluit dit venster niet, dit bericht kan niet opnieuw worden weergegeven.",
"Could not decrypt comment; Wrong key?": "Kon het commentaar niet decoderen; Verkeerde sleutel?", "Could not decrypt comment; Wrong key?": "Kon het commentaar niet decoderen; Verkeerde sleutel?",
"Reply": "Beantwoorden", "Reply": "Beantwoorden",
"Anonymous": "Anoniem", "Anonymous": "Anoniem",
"Avatar generated from IP address": "Anonieme avatar (van het IP adres)", "Avatar generated from IP address": "Anonieme avatar (van het IP-adres)",
"Add comment": "Commentaar toevoegen", "Add comment": "Commentaar toevoegen",
"Optional nickname…": "Optionele bijnaam…", "Optional nickname…": "Optionele bijnaam…",
"Post comment": "Plaats een commentaar", "Post comment": "Plaats een commentaar",
@ -125,11 +125,11 @@
"unknown status": "Onbekende status", "unknown status": "Onbekende status",
"server error or not responding": "Serverfout of server reageert niet", "server error or not responding": "Serverfout of server reageert niet",
"Could not post comment: %s": "Kon het commentaar niet plaatsen: %s", "Could not post comment: %s": "Kon het commentaar niet plaatsen: %s",
"Sending paste…": "Geplakte tekst verzenden…", "Sending paste…": "Paste verzenden…",
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Uw geplakte tekst is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Druk [Ctrl]+[c] om te kopiëren)</span>", "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Je paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Druk [Ctrl]+[c] om te kopiëren)</span>",
"Delete data": "Gegevens wissen", "Delete data": "Gegevens wissen",
"Could not create paste: %s": "Kon de geplakte tekst niet aanmaken: %s", "Could not create paste: %s": "Kon de paste niet aanmaken: %s",
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Kon de geplakte tekst niet decoderen: Decoderingssleutel ontbreekt in URL (Hebt u een redirector of een URL-verkorter gebruikt die een deel van de URL verwijdert?)", "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Kon de paste niet decoderen: Decoderingssleutel ontbreekt in URL (Heb je een redirector of een URL-verkorter gebruikt die een deel van de URL verwijdert?)",
"B": "B", "B": "B",
"KiB": "KiB", "KiB": "KiB",
"MiB": "MiB", "MiB": "MiB",
@ -145,49 +145,49 @@
"Markdown": "Markdown", "Markdown": "Markdown",
"Download attachment": "Bijlage downloaden", "Download attachment": "Bijlage downloaden",
"Cloned: '%s'": "Gekloond: '%s'", "Cloned: '%s'": "Gekloond: '%s'",
"The cloned file '%s' was attached to this paste.": "Het gekloonde bestand '%s' is bijgevoegd aan de geplakte tekst.", "The cloned file '%s' was attached to this paste.": "Het gekloonde bestand '%s' is bijgevoegd aan de paste.",
"Attach a file": "Een bestand toevoegen", "Attach a file": "Een bestand toevoegen",
"alternatively drag & drop a file or paste an image from the clipboard": "U kunt ook een bestand slepen en neerzetten of een afbeelding plakken van het klembord", "alternatively drag & drop a file or paste an image from the clipboard": "Je kunt ook een bestand slepen en neerzetten of een afbeelding plakken van het klembord",
"File too large, to display a preview. Please download the attachment.": "Het bestand is te groot om voorbeeld weer te geven. Aub de bijlage downloaden", "File too large, to display a preview. Please download the attachment.": "Het bestand is te groot om voorbeeld weer te geven. Aub de bijlage downloaden.",
"Remove attachment": "Bijlage verwijderen", "Remove attachment": "Bijlage verwijderen",
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Uw browser biedt geen ondersteuning voor het uploaden van gecodeerde bestanden. Gebruik alstublieft een nieuwere browser", "Your browser does not support uploading encrypted files. Please use a newer browser.": "Je browser biedt geen ondersteuning voor het uploaden van gecodeerde bestanden. Gebruik alstublieft een nieuwere browser.",
"Invalid attachment.": "Ongeldige bijlage", "Invalid attachment.": "Ongeldige bijlage.",
"Options": "Opties", "Options": "Opties",
"Shorten URL": "URL verkorten", "Shorten URL": "URL verkorten",
"Editor": "Editor", "Editor": "Editor",
"Preview": "Preview", "Preview": "Preview",
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vereist dat het PATH eindigt in een '%s'. Aub het PATH updaten in uw index.php.", "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vereist dat PATH eindigt in een '%s'. a.u.b. PATH updaten in je index.php.",
"Decrypt": "Decoderen", "Decrypt": "Decoderen",
"Enter password": "Voer het wachtwoord in", "Enter password": "Voer het wachtwoord in",
"Loading…": "Laden…", "Loading…": "Laden…",
"Decrypting paste…": "Geplakte tekst decoderen…", "Decrypting paste…": "Paste decoderen…",
"Preparing new paste…": "Nieuwe geplakte tekst voorbereiden…", "Preparing new paste…": "Nieuwe paste voorbereiden…",
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In het geval dat dit bericht nooit verdwijnt, kijkt u dan eens naar <a href=\"%s\"> veelgestelde vragen voor informatie over het oplossen van problemen </a>.", "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In het geval dat dit bericht nooit verdwijnt, kijkt dan eens naar <a href=\"%s\"> veelgestelde vragen voor informatie over het oplossen van problemen </a>.",
"+++ no paste text +++": "+++ geen geplakte tekst +++", "+++ no paste text +++": "+++ geen paste tekst +++",
"Could not get paste data: %s": "Kon geen klembordgegevens verkrijgen: %s", "Could not get paste data: %s": "Kon geen paste data verkrijgen: %s",
"QR code": "QR-code", "QR code": "QR-code",
"This website is using an insecure HTTP connection! Please use it only for testing.": "Deze website gebruikt een onveilige HTTP-verbinding! Gelieve deze enkel te gebruiken om te testen.", "This website is using an insecure HTTP connection! Please use it only for testing.": "Deze website gebruikt een onveilige HTTP-verbinding! Gelieve deze enkel te gebruiken om te testen.",
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Voor meer informatie <a href=\"%s\">zie dit FAQ-artikel</a>.", "For more information <a href=\"%s\">see this FAQ entry</a>.": "Voor meer informatie <a href=\"%s\">zie dit FAQ-artikel</a>.",
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Uw browser kan een HTTPS-verbinding nodig hebben om de WebCrypto API te ondersteunen. Probeer <a href=\"%s\">het met HTTPS</a>.", "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Je browser kan een HTTPS-verbinding nodig hebben om de WebCrypto API te ondersteunen. Probeer <a href=\"%s\">het met HTTPS</a>.",
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Uw browser ondersteunt WebAssembly niet, wat wordt gebruikt voor zlib compressie. U kunt niet-gecomprimeerde documenten maken, maar geen gecomprimeerde documenten lezen.", "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Je browser ondersteunt WebAssembly niet, wat wordt gebruikt voor zlib compressie. Je kunt niet-gecomprimeerde documenten maken, maar geen gecomprimeerde documenten lezen.",
"waiting on user to provide a password": "wachtend op gebruiker om een wachtwoord te geven", "waiting on user to provide a password": "wachtend op gebruiker om een wachtwoord te geven",
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Kon de gegevens niet decoderen. Heeft u een verkeerd wachtwoord ingevoerd? Probeer het opnieuw met de knop bovenaan.", "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Kon de gegevens niet decoderen. Heb je een verkeerd wachtwoord ingevoerd? Probeer het opnieuw met de knop bovenaan.",
"Retry": "Opnieuw proberen", "Retry": "Opnieuw proberen",
"Showing raw text…": "Platte tekst tonen…", "Showing raw text…": "Platte tekst tonen…",
"Notice:": "Let op:", "Notice:": "Let op:",
"This link will expire after %s.": "Deze link vervalt na %s.", "This link will expire after %s.": "Deze link vervalt na %s.",
"This link can only be accessed once, do not use back or refresh button in your browser.": "Deze link kan slechts eenmaal worden geopend, gebruik niet de terug- of verversknop in uw browser.", "This link can only be accessed once, do not use back or refresh button in your browser.": "Deze link kan slechts eenmaal worden geopend, gebruik niet de terug- of verversknop in je browser.",
"Link:": "Link:", "Link:": "Link:",
"Recipient may become aware of your timezone, convert time to UTC?": "Ontvanger kan zich bewust worden van uw tijdzone, tijd omzetten naar UTC?", "Recipient may become aware of your timezone, convert time to UTC?": "Ontvanger kan zich bewust worden van je tijdzone, tijd omzetten naar UTC?",
"Use Current Timezone": "Gebruik huidige tijdzone", "Use Current Timezone": "Gebruik huidige tijdzone",
"Convert To UTC": "Omzetten naar UTC", "Convert To UTC": "Omzetten naar UTC",
"Close": "Sluiten", "Close": "Sluiten",
"Encrypted note on %s": "Versleutelde notitie op %s", "Encrypted note on %s": "Versleutelde notitie op %s",
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Bezoek deze link om de notitie te bekijken. Als je de URL aan iemand geeft, kan die de notitie ook bekijken.", "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Bezoek deze link om de notitie te bekijken. Als je de URL aan iemand geeft, kan die de notitie ook bekijken.",
"URL shortener may expose your decrypt key in URL.": "URL-verkorter kan uw ontcijferingssleutel in URL blootleggen.", "URL shortener may expose your decrypt key in URL.": "URL-verkorter kan je ontcijferingssleutel in URL blootleggen.",
"Save paste": "Notitie opslaan", "Save paste": "Notitie opslaan",
"Your IP is not authorized to create pastes.": "Uw IP-adres is niet gemachtigd om geplakte tekst te maken.", "Your IP is not authorized to create pastes.": "Je IP-adres is niet gemachtigd om pastes te maken.",
"Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.", "Trying to shorten a URL that isn't pointing at our instance.": "Proberen om een URL te verkorten dat niet naar ons systeem wijst.",
"Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".", "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Foutmelding ophalen YOURLS. Waarschijnlijk een configuratiefout, zoals een verkeerde of missende \"apiurl\" of \"signature\".",
"Error parsing YOURLS response.": "Error parsing YOURLS response." "Error parsing YOURLS response.": "Foutmelding bij parsen van YOURLS respons."
} }

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
// change this, if your php files and data is outside of your webservers document root // change this, if your php files and data is outside of your webservers document root

View File

@ -1,6 +1,6 @@
{ {
"name": "privatebin", "name": "privatebin",
"version": "1.5.0", "version": "1.5.1",
"description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bit AES in Galois Counter mode (GCM).", "description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bit AES in Galois Counter mode (GCM).",
"main": "privatebin.js", "main": "privatebin.js",
"directories": { "directories": {

View File

@ -6,7 +6,7 @@
* @see {@link https://github.com/PrivateBin/PrivateBin} * @see {@link https://github.com/PrivateBin/PrivateBin}
* @copyright 2012 Sébastien SAUVAGE ({@link http://sebsauvage.net}) * @copyright 2012 Sébastien SAUVAGE ({@link http://sebsauvage.net})
* @license {@link https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License} * @license {@link https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License}
* @version 1.5.0 * @version 1.5.1
* @name PrivateBin * @name PrivateBin
* @namespace * @namespace
*/ */

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;
@ -28,7 +28,7 @@ class Controller
* *
* @const string * @const string
*/ */
const VERSION = '1.5.0'; const VERSION = '1.5.1';
/** /**
* minimal required PHP version * minimal required PHP version

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Data; namespace PrivateBin\Data;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Data; namespace PrivateBin\Data;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Data; namespace PrivateBin\Data;
@ -232,7 +232,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;
} }
} }
@ -362,12 +368,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 (
@ -375,11 +381,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;
@ -391,7 +399,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');
} }
@ -435,20 +443,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
* *

View File

@ -4,7 +4,7 @@
* *
* an S3 compatible data backend for PrivateBin with CEPH/RadosGW in mind * an S3 compatible data backend for PrivateBin with CEPH/RadosGW in mind
* see https://docs.ceph.com/en/latest/radosgw/s3/php/ * see https://docs.ceph.com/en/latest/radosgw/s3/php/
* based on lib/Data/GoogleCloudStorage.php from PrivateBin version 1.5.0 * based on lib/Data/GoogleCloudStorage.php from PrivateBin version 1.5.1
* *
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2022 Felix J. Ogris (https://ogris.de/) * @copyright 2022 Felix J. Ogris (https://ogris.de/)

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Model; namespace PrivateBin\Model;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Model; namespace PrivateBin\Model;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Model; namespace PrivateBin\Model;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Persistence; namespace PrivateBin\Persistence;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Persistence; namespace PrivateBin\Persistence;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Persistence; namespace PrivateBin\Persistence;

View File

@ -8,7 +8,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin\Persistence; namespace PrivateBin\Persistence;

View File

@ -7,11 +7,13 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
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';
$this->_params = Json::decode( try {
file_get_contents(self::$_inputStream) $this->_params = Json::decode(
); 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;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -8,7 +8,7 @@
* @link https://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd * @link https://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 0.0.5 beta PrivateBin 1.5.0 * @version 0.0.5 beta PrivateBin 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -7,7 +7,7 @@
* @link https://github.com/PrivateBin/PrivateBin * @link https://github.com/PrivateBin/PrivateBin
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net) * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
* @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
* @version 1.5.0 * @version 1.5.1
*/ */
namespace PrivateBin; namespace PrivateBin;

View File

@ -73,7 +73,7 @@ endif;
?> ?>
<script type="text/javascript" data-cfasync="false" src="js/purify-2.4.6.js" integrity="sha512-+jcx+EqNbaFT4OHS86zGwU1SNAAZ7hG2pJlwMpXoe9AvTp37BrXMQ29g2GhdyQHTvYWaNlTQIkWXYM0Lvt8GiQ==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/purify-2.4.6.js" integrity="sha512-+jcx+EqNbaFT4OHS86zGwU1SNAAZ7hG2pJlwMpXoe9AvTp37BrXMQ29g2GhdyQHTvYWaNlTQIkWXYM0Lvt8GiQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-4jbBDlhdAGCdPsFpAzU4qb2RoFx8FKactLHAcEkiIvott1yeQkJntlh+s/BHd5vsxdBoSgA1CeZ7sKIXL/c5vA==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-ST1B/QBH9m/TImh2pzKU88qbgwqto4N34X8bnn9+Iuye3x2pTb3aMiX5gU4gh15T7HCTw2jehB9+BtC6a/M81A==" crossorigin="anonymous"></script>
<!-- icon --> <!-- icon -->
<link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" /> <link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" /> <link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />

View File

@ -51,7 +51,7 @@ endif;
?> ?>
<script type="text/javascript" data-cfasync="false" src="js/purify-2.4.6.js" integrity="sha512-+jcx+EqNbaFT4OHS86zGwU1SNAAZ7hG2pJlwMpXoe9AvTp37BrXMQ29g2GhdyQHTvYWaNlTQIkWXYM0Lvt8GiQ==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/purify-2.4.6.js" integrity="sha512-+jcx+EqNbaFT4OHS86zGwU1SNAAZ7hG2pJlwMpXoe9AvTp37BrXMQ29g2GhdyQHTvYWaNlTQIkWXYM0Lvt8GiQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-4jbBDlhdAGCdPsFpAzU4qb2RoFx8FKactLHAcEkiIvott1yeQkJntlh+s/BHd5vsxdBoSgA1CeZ7sKIXL/c5vA==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-ST1B/QBH9m/TImh2pzKU88qbgwqto4N34X8bnn9+Iuye3x2pTb3aMiX5gU4gh15T7HCTw2jehB9+BtC6a/M81A==" crossorigin="anonymous"></script>
<!-- icon --> <!-- icon -->
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" /> <link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" /> <link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />

View File

@ -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;
} }

View File

@ -436,8 +436,6 @@ class ControllerTest extends PHPUnit_Framework_TestCase
* silently removed, check that this case is handled * silently removed, check that this case is handled
* *
* @runInSeparateProcess * @runInSeparateProcess
* @expectedException Exception
* @expectedExceptionCode 90
*/ */
public function testCreateBrokenUpload() public function testCreateBrokenUpload()
{ {
@ -449,7 +447,12 @@ class ControllerTest extends PHPUnit_Framework_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');
ob_start();
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');
} }

View File

@ -135,7 +135,7 @@ class I18nTest extends PHPUnit_Framework_TestCase
$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'cs;q=0.8,en-GB;q=0.6,en-US;q=0.4,en;q=0.2'; $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'cs;q=0.8,en-GB;q=0.6,en-US;q=0.4,en;q=0.2';
I18n::loadTranslations(); I18n::loadTranslations();
$this->assertEquals('cs', I18n::_('en'), 'browser language cs'); $this->assertEquals('cs', I18n::_('en'), 'browser language cs');
$this->assertEquals('1 hodin', I18n::_('%d hours', 1), '1 hour in Czech'); $this->assertEquals('1 hodina', I18n::_('%d hours', 1), '1 hour in Czech');
$this->assertEquals('2 hodiny', I18n::_('%d hours', 2), '2 hours in Czech'); $this->assertEquals('2 hodiny', I18n::_('%d hours', 2), '2 hours in Czech');
$this->assertEquals('5 minut', I18n::_('%d minutes', 5), '5 minutes in Czech'); $this->assertEquals('5 minut', I18n::_('%d minutes', 5), '5 minutes in Czech');
$this->assertEquals('14 minut', I18n::_('%d minutes', 14), '14 minutes in Czech'); $this->assertEquals('14 minut', I18n::_('%d minutes', 14), '14 minutes in Czech');

View File

@ -97,7 +97,7 @@ class RequestTest extends PHPUnit_Framework_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'));
} }
@ -111,7 +111,7 @@ class RequestTest extends PHPUnit_Framework_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'));
} }
@ -125,7 +125,7 @@ class RequestTest extends PHPUnit_Framework_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());
} }
@ -142,12 +142,25 @@ class RequestTest extends PHPUnit_Framework_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();