Refactored translation of exception messages

This commit is contained in:
El RIDO 2025-11-19 09:36:08 +01:00
parent 3e6f1733f9
commit 3a23117ebf
No known key found for this signature in database
GPG key ID: 0F5C940A6BD81F92
24 changed files with 186 additions and 110 deletions

View file

@ -1,7 +1,9 @@
# PrivateBin version history # PrivateBin version history
## 2.0.4 (not yet released) ## 2.0.4 (not yet released)
* CHANGED: Deduplicate JSON error message translations. * CHANGED: Deduplicate JSON error message translations
* CHANGED: Refactored translation of exception messages
* FIXED: Some exceptions not getting translated
## 1.7.9 (2025-11-13) ## 1.7.9 (2025-11-13)
* CHANGED: Upgrading libraries to: base-x 5.0.1, bootstrap 5.3.8, DOMpurify 3.2.7, ip-lib 1.21.0 & kjua 0.10.0 * CHANGED: Upgrading libraries to: base-x 5.0.1, bootstrap 5.3.8, DOMpurify 3.2.7, ip-lib 1.21.0 & kjua 0.10.0

24
composer.lock generated
View file

@ -397,16 +397,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.6.1", "version": "v5.6.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" "reference": "3a454ca033b9e06b63282ce19562e892747449bb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "reference": "3a454ca033b9e06b63282ce19562e892747449bb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -449,9 +449,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
}, },
"time": "2025-08-13T20:13:15+00:00" "time": "2025-10-21T19:32:17+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@ -2014,16 +2014,16 @@
}, },
{ {
"name": "theseer/tokenizer", "name": "theseer/tokenizer",
"version": "1.2.3", "version": "1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/theseer/tokenizer.git", "url": "https://github.com/theseer/tokenizer.git",
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" "reference": "d74205c497bfbca49f34d4bc4c19c17e22db4ebb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/d74205c497bfbca49f34d4bc4c19c17e22db4ebb",
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "reference": "d74205c497bfbca49f34d4bc4c19c17e22db4ebb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2052,7 +2052,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": { "support": {
"issues": "https://github.com/theseer/tokenizer/issues", "issues": "https://github.com/theseer/tokenizer/issues",
"source": "https://github.com/theseer/tokenizer/tree/1.2.3" "source": "https://github.com/theseer/tokenizer/tree/1.3.0"
}, },
"funding": [ "funding": [
{ {
@ -2060,7 +2060,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-03-03T12:36:25+00:00" "time": "2025-11-13T13:44:09+00:00"
} }
], ],
"aliases": [], "aliases": [],

View file

@ -12,7 +12,7 @@
namespace PrivateBin; namespace PrivateBin;
use Exception; use Exception;
use PrivateBin\TranslatedException; use PrivateBin\Exception\TranslatedException;
/** /**
* Configuration * Configuration

View file

@ -12,12 +12,13 @@
namespace PrivateBin; namespace PrivateBin;
use Exception; use Exception;
use PrivateBin\Exception\JsonException;
use PrivateBin\Exception\TranslatedException;
use PrivateBin\Persistence\ServerSalt; use PrivateBin\Persistence\ServerSalt;
use PrivateBin\Persistence\TrafficLimiter; use PrivateBin\Persistence\TrafficLimiter;
use PrivateBin\Proxy\AbstractProxy; use PrivateBin\Proxy\AbstractProxy;
use PrivateBin\Proxy\ShlinkProxy; use PrivateBin\Proxy\ShlinkProxy;
use PrivateBin\Proxy\YourlsProxy; use PrivateBin\Proxy\YourlsProxy;
use PrivateBin\TranslatedException;
/** /**
* Controller * Controller
@ -308,11 +309,10 @@ class Controller
$comment = $paste->getComment($data['parentid']); $comment = $paste->getComment($data['parentid']);
$comment->setData($data); $comment->setData($data);
$comment->store(); $comment->store();
} catch (TranslatedException $e) { $this->_json_result($comment->getId());
} catch (Exception $e) {
$this->_json_error($e->getMessage()); $this->_json_error($e->getMessage());
return;
} }
$this->_json_result($comment->getId());
} else { } else {
$this->_json_error(I18n::_('Invalid data.')); $this->_json_error(I18n::_('Invalid data.'));
} }
@ -321,21 +321,13 @@ class Controller
else { else {
try { try {
$this->_model->purge(); $this->_model->purge();
} catch (Exception $e) { // JSON error!!! $paste = $this->_model->getPaste();
error_log('Error purging documents: ' . $e->getMessage() . PHP_EOL .
'Use the administration scripts statistics to find ' .
'damaged paste IDs and either delete them or restore them ' .
'from backup.');
}
$paste = $this->_model->getPaste();
try {
$paste->setData($data); $paste->setData($data);
$paste->store(); $paste->store();
} catch (TranslatedException $e) { $this->_json_result($paste->getId(), array('deletetoken' => $paste->getDeleteToken()));
} catch (Exception $e) {
$this->_json_error($e->getMessage()); $this->_json_error($e->getMessage());
return;
} }
$this->_json_result($paste->getId(), array('deletetoken' => $paste->getDeleteToken()));
} }
} }
@ -365,7 +357,7 @@ class Controller
} else { } else {
$this->_error = self::GENERIC_ERROR; $this->_error = self::GENERIC_ERROR;
} }
} catch (Exception $e) { } catch (TranslatedException $e) {
$this->_error = $e->getMessage(); $this->_error = $e->getMessage();
} }
if ($this->_request->isJsonApiCall()) { if ($this->_request->isJsonApiCall()) {
@ -470,7 +462,7 @@ class Controller
} }
$page->assign('BASEPATH', I18n::_($this->_conf->getKey('basepath'))); $page->assign('BASEPATH', I18n::_($this->_conf->getKey('basepath')));
$page->assign('STATUS', I18n::_($this->_status)); $page->assign('STATUS', I18n::_($this->_status));
$page->assign('ISDELETED', I18n::_(json_encode($this->_is_deleted))); $page->assign('ISDELETED', $this->_is_deleted);
$page->assign('VERSION', self::VERSION); $page->assign('VERSION', self::VERSION);
$page->assign('DISCUSSION', $this->_conf->getKey('discussion')); $page->assign('DISCUSSION', $this->_conf->getKey('discussion'));
$page->assign('OPENDISCUSSION', $this->_conf->getKey('opendiscussion')); $page->assign('OPENDISCUSSION', $this->_conf->getKey('opendiscussion'));
@ -546,6 +538,7 @@ class Controller
* *
* @access private * @access private
* @param string $error * @param string $error
* @throws JsonException
*/ */
private function _json_error($error) private function _json_error($error)
{ {
@ -562,6 +555,7 @@ class Controller
* @access private * @access private
* @param string $dataid * @param string $dataid
* @param array $other * @param array $other
* @throws JsonException
*/ */
private function _json_result($dataid, $other = array()) private function _json_result($dataid, $other = array())
{ {

View file

@ -15,6 +15,7 @@ use Exception;
use PDO; use PDO;
use PDOException; use PDOException;
use PrivateBin\Controller; use PrivateBin\Controller;
use PrivateBin\Exception\JsonException;
use PrivateBin\Json; use PrivateBin\Json;
/** /**
@ -179,18 +180,24 @@ class Database extends AbstractData
'SELECT * FROM "' . $this->_sanitizeIdentifier('paste') . 'SELECT * FROM "' . $this->_sanitizeIdentifier('paste') .
'" WHERE "dataid" = ?', array($pasteid), true '" WHERE "dataid" = ?', array($pasteid), true
); );
} catch (Exception $e) { } catch (PDOException $e) {
$row = false; $row = false;
} }
if ($row === false) { if ($row === false) {
return false; return false;
} }
// create array // create array
$paste = Json::decode($row['data']); try {
$paste = Json::decode($row['data']);
} catch (JsonException $e) {
error_log('Error while reading a paste from the database: ' . $e->getMessage());
$paste = array();
}
try { try {
$paste['meta'] = Json::decode($row['meta']); $paste['meta'] = Json::decode($row['meta']);
} catch (Exception $e) { } catch (JsonException $e) {
error_log('Error while reading a paste from the database: ' . $e->getMessage());
$paste['meta'] = array(); $paste['meta'] = array();
} }
$expire_date = (int) $row['expiredate']; $expire_date = (int) $row['expiredate'];
@ -233,7 +240,7 @@ class Database extends AbstractData
'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') . 'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') .
'" WHERE "dataid" = ?', array($pasteid), true '" WHERE "dataid" = ?', array($pasteid), true
); );
} catch (Exception $e) { } catch (PDOException $e) {
return false; return false;
} }
return (bool) $row; return (bool) $row;
@ -253,7 +260,7 @@ class Database extends AbstractData
{ {
try { try {
$data = Json::encode($comment); $data = Json::encode($comment);
} catch (Exception $e) { } catch (JsonException $e) {
error_log('Error while attempting to insert a comment into the database: ' . $e->getMessage()); error_log('Error while attempting to insert a comment into the database: ' . $e->getMessage());
return false; return false;
} }
@ -274,7 +281,7 @@ class Database extends AbstractData
$meta['created'], $meta['created'],
) )
); );
} catch (Exception $e) { } catch (PDOException $e) {
error_log('Error while attempting to insert a comment into the database: ' . $e->getMessage()); error_log('Error while attempting to insert a comment into the database: ' . $e->getMessage());
return false; return false;
} }
@ -298,8 +305,14 @@ class Database extends AbstractData
$comments = array(); $comments = array();
if (count($rows)) { if (count($rows)) {
foreach ($rows as $row) { foreach ($rows as $row) {
try {
$data = Json::decode($row['data']);
} catch (JsonException $e) {
error_log('Error while reading a comment from the database: ' . $e->getMessage());
$data = array();
}
$i = $this->getOpenSlot($comments, (int) $row['postdate']); $i = $this->getOpenSlot($comments, (int) $row['postdate']);
$comments[$i] = Json::decode($row['data']); $comments[$i] = $data;
$comments[$i]['id'] = $row['dataid']; $comments[$i]['id'] = $row['dataid'];
$comments[$i]['parentid'] = $row['parentid']; $comments[$i]['parentid'] = $row['parentid'];
$comments[$i]['meta'] = array('created' => (int) $row['postdate']); $comments[$i]['meta'] = array('created' => (int) $row['postdate']);
@ -329,7 +342,7 @@ class Database extends AbstractData
'" WHERE "pasteid" = ? AND "parentid" = ? AND "dataid" = ?', '" WHERE "pasteid" = ? AND "parentid" = ? AND "dataid" = ?',
array($pasteid, $parentid, $commentid), true array($pasteid, $parentid, $commentid), true
); );
} catch (Exception $e) { } catch (PDOException $e) {
return false; return false;
} }
} }
@ -349,7 +362,8 @@ class Database extends AbstractData
$this->_last_cache[$key] = $value; $this->_last_cache[$key] = $value;
try { try {
$value = Json::encode($this->_last_cache); $value = Json::encode($this->_last_cache);
} catch (Exception $e) { } catch (JsonException $e) {
error_log('Error encoding JSON for table "config", row "traffic_limiter": ' . $e->getMessage());
return false; return false;
} }
} }
@ -393,7 +407,8 @@ class Database extends AbstractData
if ($value && $namespace === 'traffic_limiter') { if ($value && $namespace === 'traffic_limiter') {
try { try {
$this->_last_cache = Json::decode($value); $this->_last_cache = Json::decode($value);
} catch (Exception $e) { } catch (JsonException $e) {
error_log('Error decoding JSON from table "config", row "traffic_limiter": ' . $e->getMessage());
$this->_last_cache = array(); $this->_last_cache = array();
} }
if (array_key_exists($key, $this->_last_cache)) { if (array_key_exists($key, $this->_last_cache)) {
@ -412,13 +427,18 @@ class Database extends AbstractData
*/ */
protected function _getExpiredPastes($batchsize) protected function _getExpiredPastes($batchsize)
{ {
$statement = $this->_db->prepare( try {
'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') . $statement = $this->_db->prepare(
'" WHERE "expiredate" < ? AND "expiredate" != ? ' . 'SELECT "dataid" FROM "' . $this->_sanitizeIdentifier('paste') .
($this->_type === 'oci' ? 'FETCH NEXT ? ROWS ONLY' : 'LIMIT ?') '" WHERE "expiredate" < ? AND "expiredate" != ? ' .
); ($this->_type === 'oci' ? 'FETCH NEXT ? ROWS ONLY' : 'LIMIT ?')
$statement->execute(array(time(), 0, $batchsize)); );
return $statement->fetchAll(PDO::FETCH_COLUMN, 0); $statement->execute(array(time(), 0, $batchsize));
return $statement->fetchAll(PDO::FETCH_COLUMN, 0);
} catch (PDOException $e) {
error_log('Error while attempting to find expired pastes in the database: ' . $e->getMessage());
return array();
}
} }
/** /**
@ -552,6 +572,7 @@ class Database extends AbstractData
'" WHERE "id" = ?', array($key), true '" WHERE "id" = ?', array($key), true
); );
} catch (PDOException $e) { } catch (PDOException $e) {
error_log('Error while attempting to fetch configuration key "' . $key . '" in the database: ' . $e->getMessage());
return ''; return '';
} }
return $row ? $row['value'] : ''; return $row ? $row['value'] : '';

View file

@ -11,8 +11,8 @@
namespace PrivateBin\Data; namespace PrivateBin\Data;
use Exception;
use GlobIterator; use GlobIterator;
use PrivateBin\Exception\JsonException;
use PrivateBin\Json; use PrivateBin\Json;
/** /**
@ -104,13 +104,10 @@ class Filesystem extends AbstractData
*/ */
public function read($pasteid) public function read($pasteid)
{ {
if ( if ($this->exists($pasteid)) {
!$this->exists($pasteid) || return $this->_get($this->_dataid2path($pasteid) . $pasteid . '.php');
!$paste = $this->_get($this->_dataid2path($pasteid) . $pasteid . '.php')
) {
return false;
} }
return $paste; return false;
} }
/** /**
@ -346,7 +343,12 @@ class Filesystem extends AbstractData
file_get_contents($filename), file_get_contents($filename),
strlen(self::PROTECTION_LINE . PHP_EOL) strlen(self::PROTECTION_LINE . PHP_EOL)
); );
return Json::decode($data); try {
return Json::decode($data);
} catch (JsonException $e) {
error_log('Error decoding JSON from "' . $filename . '": ' . $e->getMessage());
return false;
}
} }
/** /**
@ -450,7 +452,7 @@ class Filesystem extends AbstractData
$filename, $filename,
self::PROTECTION_LINE . PHP_EOL . Json::encode($data) self::PROTECTION_LINE . PHP_EOL . Json::encode($data)
); );
} catch (Exception $e) { } catch (JsonException $e) {
error_log('Error while trying to store data to the filesystem at path "' . $filename . '": ' . $e->getMessage()); error_log('Error while trying to store data to the filesystem at path "' . $filename . '": ' . $e->getMessage());
return false; return false;
} }

View file

@ -15,6 +15,7 @@ use Exception;
use Google\Cloud\Core\Exception\NotFoundException; use Google\Cloud\Core\Exception\NotFoundException;
use Google\Cloud\Storage\Bucket; use Google\Cloud\Storage\Bucket;
use Google\Cloud\Storage\StorageClient; use Google\Cloud\Storage\StorageClient;
use PrivateBin\Exception\JsonException;
use PrivateBin\Json; use PrivateBin\Json;
class GoogleCloudStorage extends AbstractData class GoogleCloudStorage extends AbstractData
@ -219,7 +220,12 @@ class GoogleCloudStorage extends AbstractData
try { try {
foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) { foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) {
$data = $this->_bucket->object($key->name())->downloadAsString(); $data = $this->_bucket->object($key->name())->downloadAsString();
$comment = Json::decode($data); try {
$comment = Json::decode($data);
} catch (JsonException $e) {
error_log('failed to read comment from ' . $key->name() . ', ' . $e->getMessage());
$comment = array();
}
$comment['id'] = basename($key->name()); $comment['id'] = basename($key->name());
$slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']); $slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
$comments[$slot] = $comment; $comments[$slot] = $comment;

View file

@ -37,6 +37,7 @@ namespace PrivateBin\Data;
use Aws\S3\Exception\S3Exception; use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client; use Aws\S3\S3Client;
use PrivateBin\Exception\JsonException;
use PrivateBin\Json; use PrivateBin\Json;
class S3Storage extends AbstractData class S3Storage extends AbstractData
@ -177,12 +178,14 @@ class S3Storage extends AbstractData
'ContentType' => 'application/json', 'ContentType' => 'application/json',
'Metadata' => $metadata, 'Metadata' => $metadata,
)); ));
return true;
} catch (S3Exception $e) { } catch (S3Exception $e) {
error_log('failed to upload ' . $key . ' to ' . $this->_bucket . ', ' . error_log('failed to upload ' . $key . ' to ' . $this->_bucket . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage()))); trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));
return false; } catch (JsonException $e) {
error_log('failed to JSON encode ' . $key . ', ' . $e->getMessage());
} }
return true; return false;
} }
/** /**
@ -212,8 +215,10 @@ class S3Storage extends AbstractData
} catch (S3Exception $e) { } catch (S3Exception $e) {
error_log('failed to read ' . $pasteid . ' from ' . $this->_bucket . ', ' . error_log('failed to read ' . $pasteid . ' from ' . $this->_bucket . ', ' .
trim(preg_replace('/\s\s+/', ' ', $e->getMessage()))); trim(preg_replace('/\s\s+/', ' ', $e->getMessage())));
return false; } catch (JsonException $e) {
error_log('failed to JSON decode ' . $key . ', ' . $e->getMessage());
} }
return false;
} }
/** /**

View file

@ -0,0 +1,37 @@
<?php declare(strict_types=1);
/**
* 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
*/
namespace PrivateBin\Exception;
use Exception;
/**
* JsonException
*
* An Exception representing JSON en- or decoding errors.
*/
class JsonException extends Exception
{
/**
* Exception constructor with mandatory JSON error code.
*
* @access public
* @param int $code
*/
public function __construct(int $code) {
$message = 'A JSON error occurred';
if (function_exists('json_last_error_msg')) {
$message .= ': ' . json_last_error_msg();
}
$message .= ' (' . $code . ')';
parent::__construct($message, 90);
}
}

View file

@ -9,7 +9,7 @@
* @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
*/ */
namespace PrivateBin; namespace PrivateBin\Exception;
use Exception; use Exception;
use PrivateBin\I18n; use PrivateBin\I18n;

View file

@ -162,6 +162,7 @@ class I18n
* *
* @access public * @access public
* @static * @static
* @throws JsonException
*/ */
public static function loadTranslations() public static function loadTranslations()
{ {
@ -270,6 +271,7 @@ class I18n
* @access public * @access public
* @static * @static
* @param array $languages * @param array $languages
* @throws JsonException
* @return array * @return array
*/ */
public static function getLanguageLabels($languages = array()) public static function getLanguageLabels($languages = array())

View file

@ -11,7 +11,7 @@
namespace PrivateBin; namespace PrivateBin;
use Exception; use PrivateBin\Exception\JsonException;
/** /**
* Json * Json
@ -26,7 +26,7 @@ class Json
* @access public * @access public
* @static * @static
* @param mixed $input * @param mixed $input
* @throws Exception * @throws JsonException
* @return string * @return string
*/ */
public static function encode(&$input) public static function encode(&$input)
@ -42,7 +42,7 @@ class Json
* @access public * @access public
* @static * @static
* @param string $input * @param string $input
* @throws Exception * @throws JsonException
* @return mixed * @return mixed
*/ */
public static function decode(&$input) public static function decode(&$input)
@ -57,21 +57,14 @@ class Json
* *
* @access private * @access private
* @static * @static
* @throws Exception * @throws JsonException
* @return void * @return void
*/ */
private static function _detectError() private static function _detectError()
{ {
$errorCode = json_last_error(); $errorCode = json_last_error();
if ($errorCode === JSON_ERROR_NONE) { if ($errorCode !== JSON_ERROR_NONE) {
return; throw new JsonException($errorCode);
} }
$message = 'A JSON error occurred';
if (function_exists('json_last_error_msg')) {
$message .= ': ' . json_last_error_msg();
}
$message .= ' (' . $errorCode . ')';
throw new Exception($message, 90);
} }
} }

View file

@ -13,7 +13,7 @@ namespace PrivateBin\Model;
use PrivateBin\Configuration; use PrivateBin\Configuration;
use PrivateBin\Data\AbstractData; use PrivateBin\Data\AbstractData;
use PrivateBin\TranslatedException; use PrivateBin\Exception\TranslatedException;
/** /**
* AbstractModel * AbstractModel

View file

@ -13,8 +13,8 @@ namespace PrivateBin\Model;
use Identicon\Identicon; use Identicon\Identicon;
use Jdenticon\Identicon as Jdenticon; use Jdenticon\Identicon as Jdenticon;
use PrivateBin\Exception\TranslatedException;
use PrivateBin\Persistence\TrafficLimiter; use PrivateBin\Persistence\TrafficLimiter;
use PrivateBin\TranslatedException;
use PrivateBin\Vizhash16x16; use PrivateBin\Vizhash16x16;
/** /**

View file

@ -12,8 +12,8 @@
namespace PrivateBin\Model; namespace PrivateBin\Model;
use PrivateBin\Controller; use PrivateBin\Controller;
use PrivateBin\Exception\TranslatedException;
use PrivateBin\Persistence\ServerSalt; use PrivateBin\Persistence\ServerSalt;
use PrivateBin\TranslatedException;
/** /**
* Paste * Paste

View file

@ -15,7 +15,7 @@ namespace PrivateBin\Persistence;
use IPLib\Factory; use IPLib\Factory;
use IPLib\ParseStringFlag; use IPLib\ParseStringFlag;
use PrivateBin\Configuration; use PrivateBin\Configuration;
use PrivateBin\TranslatedException; use PrivateBin\Exception\TranslatedException;
/** /**
* TrafficLimiter * TrafficLimiter

View file

@ -11,8 +11,8 @@
namespace PrivateBin\Proxy; namespace PrivateBin\Proxy;
use Exception;
use PrivateBin\Configuration; use PrivateBin\Configuration;
use PrivateBin\Exception\JsonException;
use PrivateBin\Json; use PrivateBin\Json;
/** /**
@ -90,7 +90,7 @@ abstract class AbstractProxy
try { try {
$jsonData = Json::decode($data); $jsonData = Json::decode($data);
} catch (Exception $e) { } catch (JsonException $e) {
$this->_error = 'Proxy error: Error parsing proxy response. This can be a configuration issue, like wrong or missing config keys.'; $this->_error = 'Proxy error: Error parsing proxy response. This can be a configuration issue, like wrong or missing config keys.';
$this->logErrorWithClassName('Error calling proxy: ' . $e->getMessage()); $this->logErrorWithClassName('Error calling proxy: ' . $e->getMessage());
return; return;

View file

@ -12,6 +12,7 @@
namespace PrivateBin\Proxy; namespace PrivateBin\Proxy;
use PrivateBin\Configuration; use PrivateBin\Configuration;
use PrivateBin\Exception\JsonException;
use PrivateBin\Json; use PrivateBin\Json;
/** /**
@ -48,12 +49,17 @@ class ShlinkProxy extends AbstractProxy
'longUrl' => $link, 'longUrl' => $link,
); );
return array( try {
'method' => 'POST', return array(
'header' => "Content-Type: application/json\r\n" . 'method' => 'POST',
'X-Api-Key: ' . $shlink_api_key . "\r\n", 'header' => "Content-Type: application/json\r\n" .
'content' => Json::encode($body), 'X-Api-Key: ' . $shlink_api_key . "\r\n",
); 'content' => Json::encode($body),
);
} catch (JsonException $e) {
error_log('[' . get_class($this) . '] Error encoding body: ' . $e->getMessage());
return array();
}
} }
/** /**

View file

@ -11,7 +11,7 @@
namespace PrivateBin; namespace PrivateBin;
use Exception; use PrivateBin\Exception\JsonException;
use PrivateBin\Model\Paste; use PrivateBin\Model\Paste;
/** /**
@ -113,7 +113,7 @@ class Request
try { try {
$data = file_get_contents(self::$_inputStream); $data = file_get_contents(self::$_inputStream);
$this->_params = Json::decode($data); $this->_params = Json::decode($data);
} catch (Exception $e) { } catch (JsonException $e) {
// ignore error, $this->_params will remain empty // ignore error, $this->_params will remain empty
} }
break; break;

View file

@ -513,16 +513,19 @@ if ($FILEUPLOAD) :
<?php <?php
endif; endif;
?> ?>
<div id="status" role="alert" class="clearfix alert alert-<?php echo (bool)$ISDELETED ? 'success' : 'info'; echo empty($STATUS) ? ' hidden' : '' ?>"> <div id="status" role="alert" class="clearfix alert alert-<?php echo $ISDELETED ? 'success' : 'info'; echo empty($STATUS) ? ' hidden' : '' ?>">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
<?php echo I18n::encode($STATUS), PHP_EOL; ?> <?php echo I18n::encode($STATUS), PHP_EOL; ?>
<?php <?php
if ((bool)$ISDELETED): if ($ISDELETED) :
?> ?>
<button type="button" class="btn btn-default pull-right" id="new-from-alert"> <button type="button" class="btn btn-default pull-right" id="new-from-alert">
<span class="glyphicon glyphicon-repeat"></span> <?php echo I18n::_('Start over'), PHP_EOL; ?> <span class="glyphicon glyphicon-repeat"></span>
</button> <?php echo I18n::_('Start over'), PHP_EOL; ?>
<?php endif; ?> </button>
<?php
endif;
?>
</div> </div>
<div id="errormessage" role="alert" class="<?php echo empty($ERROR) ? 'hidden' : '' ?> alert alert-danger"> <div id="errormessage" role="alert" class="<?php echo empty($ERROR) ? 'hidden' : '' ?> alert alert-danger">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span> <span class="glyphicon glyphicon-alert" aria-hidden="true"></span>

View file

@ -378,18 +378,21 @@ if ($FILEUPLOAD) :
<?php <?php
endif; endif;
?> ?>
<div id="status" role="alert" class="d-flex justify-content-between align-items-center alert alert-<?php echo (bool)$ISDELETED ? 'success' : 'info'; echo empty($STATUS) ? ' hidden' : '' ?>"> <div id="status" role="alert" class="d-flex justify-content-between align-items-center alert alert-<?php echo $ISDELETED ? 'success' : 'info'; echo empty($STATUS) ? ' hidden' : '' ?>">
<div> <div>
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#info-circle" /></svg> <svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#info-circle" /></svg>
<?php echo I18n::encode($STATUS), PHP_EOL; ?> <?php echo I18n::encode($STATUS), PHP_EOL; ?>
</div> </div>
<?php <?php
if ((bool)$ISDELETED): if ($ISDELETED) :
?> ?>
<button type="button" class="btn btn-secondary d-flex justify-content-center align-items-center gap-1" id="new-from-alert"> <button type="button" class="btn btn-secondary d-flex justify-content-center align-items-center gap-1" id="new-from-alert">
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#repeat" /></svg> <?php echo I18n::_('Start over'), PHP_EOL; ?> <svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#repeat" /></svg>
</button> <?php echo I18n::_('Start over'), PHP_EOL; ?>
<?php endif; ?> </button>
<?php
endif;
?>
</div> </div>
<div id="errormessage" role="alert" class="<?php echo empty($ERROR) ? 'hidden' : '' ?> alert alert-danger"> <div id="errormessage" role="alert" class="<?php echo empty($ERROR) ? 'hidden' : '' ?> alert alert-danger">
<svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#exclamation-triangle" /></svg> <svg width="16" height="16" fill="currentColor" aria-hidden="true"><use href="img/bootstrap-icons.svg#exclamation-triangle" /></svg>

View file

@ -74,6 +74,8 @@ return array(
'PrivateBin\\Data\\Filesystem' => $baseDir . '/lib/Data/Filesystem.php', 'PrivateBin\\Data\\Filesystem' => $baseDir . '/lib/Data/Filesystem.php',
'PrivateBin\\Data\\GoogleCloudStorage' => $baseDir . '/lib/Data/GoogleCloudStorage.php', 'PrivateBin\\Data\\GoogleCloudStorage' => $baseDir . '/lib/Data/GoogleCloudStorage.php',
'PrivateBin\\Data\\S3Storage' => $baseDir . '/lib/Data/S3Storage.php', 'PrivateBin\\Data\\S3Storage' => $baseDir . '/lib/Data/S3Storage.php',
'PrivateBin\\Exception\\JsonException' => $baseDir . '/lib/Exception/JsonException.php',
'PrivateBin\\Exception\\TranslatedException' => $baseDir . '/lib/Exception/TranslatedException.php',
'PrivateBin\\Filter' => $baseDir . '/lib/Filter.php', 'PrivateBin\\Filter' => $baseDir . '/lib/Filter.php',
'PrivateBin\\FormatV2' => $baseDir . '/lib/FormatV2.php', 'PrivateBin\\FormatV2' => $baseDir . '/lib/FormatV2.php',
'PrivateBin\\I18n' => $baseDir . '/lib/I18n.php', 'PrivateBin\\I18n' => $baseDir . '/lib/I18n.php',
@ -91,7 +93,6 @@ return array(
'PrivateBin\\Proxy\\YourlsProxy' => $baseDir . '/lib/Proxy/YourlsProxy.php', 'PrivateBin\\Proxy\\YourlsProxy' => $baseDir . '/lib/Proxy/YourlsProxy.php',
'PrivateBin\\Request' => $baseDir . '/lib/Request.php', 'PrivateBin\\Request' => $baseDir . '/lib/Request.php',
'PrivateBin\\TemplateSwitcher' => $baseDir . '/lib/TemplateSwitcher.php', 'PrivateBin\\TemplateSwitcher' => $baseDir . '/lib/TemplateSwitcher.php',
'PrivateBin\\TranslatedException' => $baseDir . '/lib/TranslatedException.php',
'PrivateBin\\View' => $baseDir . '/lib/View.php', 'PrivateBin\\View' => $baseDir . '/lib/View.php',
'PrivateBin\\Vizhash16x16' => $baseDir . '/lib/Vizhash16x16.php', 'PrivateBin\\Vizhash16x16' => $baseDir . '/lib/Vizhash16x16.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',

View file

@ -122,6 +122,8 @@ class ComposerStaticInitDontChange
'PrivateBin\\Data\\Filesystem' => __DIR__ . '/../..' . '/lib/Data/Filesystem.php', 'PrivateBin\\Data\\Filesystem' => __DIR__ . '/../..' . '/lib/Data/Filesystem.php',
'PrivateBin\\Data\\GoogleCloudStorage' => __DIR__ . '/../..' . '/lib/Data/GoogleCloudStorage.php', 'PrivateBin\\Data\\GoogleCloudStorage' => __DIR__ . '/../..' . '/lib/Data/GoogleCloudStorage.php',
'PrivateBin\\Data\\S3Storage' => __DIR__ . '/../..' . '/lib/Data/S3Storage.php', 'PrivateBin\\Data\\S3Storage' => __DIR__ . '/../..' . '/lib/Data/S3Storage.php',
'PrivateBin\\Exception\\JsonException' => __DIR__ . '/../..' . '/lib/Exception/JsonException.php',
'PrivateBin\\Exception\\TranslatedException' => __DIR__ . '/../..' . '/lib/Exception/TranslatedException.php',
'PrivateBin\\Filter' => __DIR__ . '/../..' . '/lib/Filter.php', 'PrivateBin\\Filter' => __DIR__ . '/../..' . '/lib/Filter.php',
'PrivateBin\\FormatV2' => __DIR__ . '/../..' . '/lib/FormatV2.php', 'PrivateBin\\FormatV2' => __DIR__ . '/../..' . '/lib/FormatV2.php',
'PrivateBin\\I18n' => __DIR__ . '/../..' . '/lib/I18n.php', 'PrivateBin\\I18n' => __DIR__ . '/../..' . '/lib/I18n.php',
@ -139,7 +141,6 @@ class ComposerStaticInitDontChange
'PrivateBin\\Proxy\\YourlsProxy' => __DIR__ . '/../..' . '/lib/Proxy/YourlsProxy.php', 'PrivateBin\\Proxy\\YourlsProxy' => __DIR__ . '/../..' . '/lib/Proxy/YourlsProxy.php',
'PrivateBin\\Request' => __DIR__ . '/../..' . '/lib/Request.php', 'PrivateBin\\Request' => __DIR__ . '/../..' . '/lib/Request.php',
'PrivateBin\\TemplateSwitcher' => __DIR__ . '/../..' . '/lib/TemplateSwitcher.php', 'PrivateBin\\TemplateSwitcher' => __DIR__ . '/../..' . '/lib/TemplateSwitcher.php',
'PrivateBin\\TranslatedException' => __DIR__ . '/../..' . '/lib/TranslatedException.php',
'PrivateBin\\View' => __DIR__ . '/../..' . '/lib/View.php', 'PrivateBin\\View' => __DIR__ . '/../..' . '/lib/View.php',
'PrivateBin\\Vizhash16x16' => __DIR__ . '/../..' . '/lib/Vizhash16x16.php', 'PrivateBin\\Vizhash16x16' => __DIR__ . '/../..' . '/lib/Vizhash16x16.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',

View file

@ -3,7 +3,7 @@
'name' => 'privatebin/privatebin', 'name' => 'privatebin/privatebin',
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => 'a051c4bd6b71fd56f0d7fc235e815dafc8eb54ea', 'reference' => '8eb39b4ffa8daed3d8ff0279c9870ee5b6b0bd95',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -31,7 +31,7 @@
'privatebin/privatebin' => array( 'privatebin/privatebin' => array(
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => 'a051c4bd6b71fd56f0d7fc235e815dafc8eb54ea', 'reference' => '8eb39b4ffa8daed3d8ff0279c9870ee5b6b0bd95',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),