Browse Source

fix: skip corrupt filesystem comments

Jose Tejera 1 month ago
parent
commit
1985588289
2 changed files with 34 additions and 1 deletions
  1. 11 1
      lib/Data/Filesystem.php
  2. 23 0
      tst/Data/FilesystemTest.php

+ 11 - 1
lib/Data/Filesystem.php

@@ -214,8 +214,18 @@ class Filesystem extends AbstractData
                 // - commentid is the comment identifier itself.
                 // - parentid is the comment this comment replies to (It can be pasteid)
                 if ($file->isFile()) {
+                    $items = explode('.', $file->getBasename('.php'));
+                    if (count($items) !== 3) {
+                        continue;
+                    }
                     $comment = $this->_get($file->getPathname());
-                    $items   = explode('.', $file->getBasename('.php'));
+                    if (
+                        !is_array($comment) ||
+                        !isset($comment['meta']['created']) ||
+                        !(is_int($comment['meta']['created']) || is_string($comment['meta']['created']))
+                    ) {
+                        continue;
+                    }
                     // Add some meta information not contained in file.
                     $comment['id']       = $items[1];
                     $comment['parentid'] = $items[2];

+ 23 - 0
tst/Data/FilesystemTest.php

@@ -75,6 +75,29 @@ class FilesystemTest extends TestCase
         $this->assertEquals($original, $this->_model->read(Helper::getPasteId()));
     }
 
+    public function testCorruptCommentsAreIgnored()
+    {
+        $pasteid   = Helper::getPasteId();
+        $commentid = Helper::getCommentId();
+        $comment   = Helper::getComment();
+        $this->assertTrue($this->_model->createComment($pasteid, $pasteid, $commentid, $comment));
+
+        $discussionPath = $this->_path . DIRECTORY_SEPARATOR . substr($pasteid, 0, 2) .
+            DIRECTORY_SEPARATOR . substr($pasteid, 2, 2) . DIRECTORY_SEPARATOR .
+            $pasteid . '.discussion' . DIRECTORY_SEPARATOR;
+        file_put_contents(
+            $discussionPath . $pasteid . '.ffffffffffffffff.' . $pasteid . '.php',
+            Filesystem::PROTECTION_LINE . PHP_EOL . '{'
+        );
+
+        $errorLog = ini_get('error_log');
+        ini_set('error_log', '/dev/null');
+        $comments = $this->_model->readComments($pasteid);
+        ini_set('error_log', $errorLog);
+        $this->assertCount(1, $comments);
+        $this->assertSame($commentid, current($comments)['id']);
+    }
+
     /**
      * pastes a-g are expired and should get deleted, x never expires and y-z expire in an hour
      */