From 629f263cf501b6bd8f01e0285c4429f3c3079f67 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Tue, 11 Mar 2025 07:59:10 +0100 Subject: [PATCH] pass by reference, closes #858 --- CHANGELOG.md | 1 + lib/Data/Filesystem.php | 9 ++++----- lib/Data/GoogleCloudStorage.php | 3 ++- lib/FormatV2.php | 2 +- lib/I18n.php | 12 ++++++++---- lib/Json.php | 4 ++-- lib/Model/AbstractModel.php | 9 ++++----- lib/Model/Comment.php | 6 ++---- lib/Model/Paste.php | 8 +++----- lib/Request.php | 5 ++--- tst/FormatV2Test.php | 10 ++++++---- tst/ModelTest.php | 3 ++- 12 files changed, 37 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbe5818b..ce4408ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 1.7.7 (not yet released) * ADDED: Switching templates using the web ui (#1501) +* CHANGED: Passing large data structures by reference to reduce memory consumption (#858) * CHANGED: Upgrading libraries to: ip-lib 1.20.0 ## 1.7.6 (2025-02-01) diff --git a/lib/Data/Filesystem.php b/lib/Data/Filesystem.php index 506ab4ee..be32c6ec 100644 --- a/lib/Data/Filesystem.php +++ b/lib/Data/Filesystem.php @@ -343,12 +343,11 @@ class Filesystem extends AbstractData */ private function _get($filename) { - return Json::decode( - substr( - file_get_contents($filename), - strlen(self::PROTECTION_LINE . PHP_EOL) - ) + $data = substr( + file_get_contents($filename), + strlen(self::PROTECTION_LINE . PHP_EOL) ); + return Json::decode($data); } /** diff --git a/lib/Data/GoogleCloudStorage.php b/lib/Data/GoogleCloudStorage.php index 45af05ee..c4354e83 100644 --- a/lib/Data/GoogleCloudStorage.php +++ b/lib/Data/GoogleCloudStorage.php @@ -219,7 +219,8 @@ class GoogleCloudStorage extends AbstractData $prefix = $this->_getKey($pasteid) . '/discussion/'; try { foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $key) { - $comment = JSON::decode($this->_bucket->object($key->name())->downloadAsString()); + $data = $this->_bucket->object($key->name())->downloadAsString(); + $comment = Json::decode($data); $comment['id'] = basename($key->name()); $slot = $this->getOpenSlot($comments, (int) $comment['meta']['created']); $comments[$slot] = $comment; diff --git a/lib/FormatV2.php b/lib/FormatV2.php index 070c820a..6660c4f3 100644 --- a/lib/FormatV2.php +++ b/lib/FormatV2.php @@ -29,7 +29,7 @@ class FormatV2 * @param bool $isComment * @return bool */ - public static function isValid($message, $isComment = false) + public static function isValid(&$message, $isComment = false) { $required_keys = array('adata', 'v', 'ct'); if ($isComment) { diff --git a/lib/I18n.php b/lib/I18n.php index 2ef9effd..e99946f6 100644 --- a/lib/I18n.php +++ b/lib/I18n.php @@ -183,9 +183,12 @@ class I18n // load translations self::$_language = $match; - self::$_translations = ($match == 'en') ? array() : Json::decode( - file_get_contents(self::_getPath($match . '.json')) - ); + if ($match == 'en') { + self::$_translations = array(); + } else { + $data = file_get_contents(self::_getPath($match . '.json')); + self::$_translations = Json::decode($data); + } } /** @@ -273,7 +276,8 @@ class I18n { $file = self::_getPath('languages.json'); if (count(self::$_languageLabels) == 0 && is_readable($file)) { - self::$_languageLabels = Json::decode(file_get_contents($file)); + $data = file_get_contents($file); + self::$_languageLabels = Json::decode($data); } if (count($languages) == 0) { return self::$_languageLabels; diff --git a/lib/Json.php b/lib/Json.php index 9985f16e..cc405575 100644 --- a/lib/Json.php +++ b/lib/Json.php @@ -29,7 +29,7 @@ class Json * @throws Exception * @return string */ - public static function encode($input) + public static function encode(&$input) { $jsonString = json_encode($input); self::_detectError(); @@ -45,7 +45,7 @@ class Json * @throws Exception * @return mixed */ - public static function decode($input) + public static function decode(&$input) { $output = json_decode($input, true); self::_detectError(); diff --git a/lib/Model/AbstractModel.php b/lib/Model/AbstractModel.php index fb43400e..71f7c14a 100644 --- a/lib/Model/AbstractModel.php +++ b/lib/Model/AbstractModel.php @@ -100,9 +100,9 @@ abstract class AbstractModel * @param array $data * @throws Exception */ - public function setData(array $data) + public function setData(array &$data) { - $data = $this->_sanitize($data); + $this->_sanitize($data); $this->_validate($data); $this->_data = $data; @@ -163,9 +163,8 @@ abstract class AbstractModel * * @access protected * @param array $data - * @return array */ - abstract protected function _sanitize(array $data); + abstract protected function _sanitize(array &$data); /** * Validate data. @@ -174,7 +173,7 @@ abstract class AbstractModel * @param array $data * @throws Exception */ - protected function _validate(array $data) + protected function _validate(array &$data) { } } diff --git a/lib/Model/Comment.php b/lib/Model/Comment.php index 5250eb83..eb4d371d 100644 --- a/lib/Model/Comment.php +++ b/lib/Model/Comment.php @@ -104,7 +104,7 @@ class Comment extends AbstractModel * @param Paste $paste * @throws Exception */ - public function setPaste(Paste $paste) + public function setPaste(Paste &$paste) { $this->_paste = $paste; $this->_data['pasteid'] = $paste->getId(); @@ -155,9 +155,8 @@ class Comment extends AbstractModel * * @access protected * @param array $data - * @return array */ - protected function _sanitize(array $data) + protected function _sanitize(array &$data) { // we generate an icon based on a SHA512 HMAC of the users IP, if configured $icon = $this->_conf->getKey('icon'); @@ -190,6 +189,5 @@ class Comment extends AbstractModel $data['meta']['icon'] = $pngdata; } } - return $data; } } diff --git a/lib/Model/Paste.php b/lib/Model/Paste.php index 76dc4b4c..d95dc7c0 100644 --- a/lib/Model/Paste.php +++ b/lib/Model/Paste.php @@ -219,11 +219,10 @@ class Paste extends AbstractModel * * @access protected * @param array $data - * @return array */ - protected function _sanitize(array $data) + protected function _sanitize(array &$data) { - $expiration = $data['meta']['expire']; + $expiration = $data['meta']['expire'] ?? 0; unset($data['meta']['expire']); $expire_options = $this->_conf->getSection('expire_options'); if (array_key_exists($expiration, $expire_options)) { @@ -235,7 +234,6 @@ class Paste extends AbstractModel if ($expire > 0) { $data['meta']['expire_date'] = time() + $expire; } - return $data; } /** @@ -245,7 +243,7 @@ class Paste extends AbstractModel * @param array $data * @throws Exception */ - protected function _validate(array $data) + protected function _validate(array &$data) { // reject invalid or disabled formatters if (!array_key_exists($data['adata'][1], $this->_conf->getSection('formatter_options'))) { diff --git a/lib/Request.php b/lib/Request.php index 53a8adb0..0a2c11d5 100644 --- a/lib/Request.php +++ b/lib/Request.php @@ -110,9 +110,8 @@ class Request // it might be a creation or a deletion, the latter is detected below $this->_operation = 'create'; try { - $this->_params = Json::decode( - file_get_contents(self::$_inputStream) - ); + $data = file_get_contents(self::$_inputStream); + $this->_params = Json::decode($data); } catch (Exception $e) { // ignore error, $this->_params will remain empty } diff --git a/tst/FormatV2Test.php b/tst/FormatV2Test.php index cf6cf565..2e13d8f5 100644 --- a/tst/FormatV2Test.php +++ b/tst/FormatV2Test.php @@ -7,10 +7,11 @@ class FormatV2Test extends TestCase { public function testFormatV2ValidatorValidatesCorrectly() { - $this->assertTrue(FormatV2::isValid(Helper::getPastePost()), 'valid format'); - $this->assertTrue(FormatV2::isValid(Helper::getCommentPost(), true), 'valid format'); + $paste = Helper::getPastePost(); + $comment = Helper::getCommentPost(); + $this->assertTrue(FormatV2::isValid($paste), 'valid format'); + $this->assertTrue(FormatV2::isValid($comment, true), 'valid format'); - $paste = Helper::getPastePost(); $paste['adata'][0][0] = '$'; $this->assertFalse(FormatV2::isValid($paste), 'invalid base64 encoding of iv'); @@ -68,6 +69,7 @@ class FormatV2Test extends TestCase $paste['adata'][0][7] = '!#@'; $this->assertFalse(FormatV2::isValid($paste), 'invalid compression'); - $this->assertFalse(FormatV2::isValid(Helper::getPaste()), 'invalid meta key'); + $paste = Helper::getPaste(); + $this->assertFalse(FormatV2::isValid($paste), 'invalid meta key'); } } diff --git a/tst/ModelTest.php b/tst/ModelTest.php index 04609e22..99acba1f 100644 --- a/tst/ModelTest.php +++ b/tst/ModelTest.php @@ -163,7 +163,8 @@ class ModelTest extends TestCase $this->_conf->getSection('model_options') ) ); - $comment->setPaste($this->_model->getPaste(Helper::getPasteId())); + $paste = $this->_model->getPaste(Helper::getPasteId()); + $comment->setPaste($paste); $this->assertEquals(Helper::getPasteId(), $comment->getParentId(), 'comment parent ID gets initialized to paste ID'); }