" . $this->theme->build_thumb_html($image) . "
" . diff --git a/ext/s3/main.php b/ext/s3/main.php index 84afea2d..6668a61b 100644 --- a/ext/s3/main.php +++ b/ext/s3/main.php @@ -131,7 +131,7 @@ class S3 extends Extension global $config, $page, $user; if ($event->page_matches("s3/sync/{image_id}", method: "POST", permission: Permissions::DELETE_IMAGE)) { $id = $event->get_iarg('image_id'); - $this->sync_post(Image::by_id($id)); + $this->sync_post(Image::by_id_ex($id)); log_info("s3", "Manual resync for >>$id", "File re-sync'ed"); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$id")); @@ -237,7 +237,7 @@ class S3 extends Extension $client->putObject([ 'Bucket' => $image_bucket, 'Key' => $key, - 'Body' => file_get_contents_ex($image->get_image_filename()), + 'Body' => \Safe\file_get_contents($image->get_image_filename()), 'ACL' => 'public-read', 'ContentType' => $image->get_mime(), 'ContentDisposition' => "inline; filename=\"$friendly\"", diff --git a/ext/setup/main.php b/ext/setup/main.php index bb8d2f37..78352f24 100644 --- a/ext/setup/main.php +++ b/ext/setup/main.php @@ -326,7 +326,7 @@ class Setup extends Extension if ($event->page_starts_with("nicedebug")) { $page->set_mode(PageMode::DATA); - $page->set_data(json_encode_ex([ + $page->set_data(\Safe\json_encode([ "args" => $event->args, ])); } @@ -354,9 +354,12 @@ class Setup extends Extension public function onSetupBuilding(SetupBuildingEvent $event): void { $themes = []; - foreach (glob_ex("themes/*") as $theme_dirname) { + foreach (\Safe\glob("themes/*") as $theme_dirname) { $name = str_replace("themes/", "", $theme_dirname); $human = str_replace("_", " ", $name); + // while phpstan-safe-rule isn't enabled, phpstan can't tell + // that \Safe\glob() returns string[] + // @phpstan-ignore-next-line $human = ucwords($human); $themes[$human] = $name; } @@ -405,7 +408,7 @@ class Setup extends Extension } } log_warning("setup", "Configuration updated"); - foreach (glob_ex("data/cache/*.css") as $css_cache) { + foreach (\Safe\glob("data/cache/*.css") as $css_cache) { unlink($css_cache); } log_warning("setup", "Cache cleared"); diff --git a/ext/sitemap/main.php b/ext/sitemap/main.php index c8c82dda..5310d43a 100644 --- a/ext/sitemap/main.php +++ b/ext/sitemap/main.php @@ -29,7 +29,7 @@ class XMLSitemap extends Extension file_put_contents($cache_path, $xml); } - $xml = file_get_contents_ex($cache_path); + $xml = \Safe\file_get_contents($cache_path); $page->set_mode(PageMode::DATA); $page->set_mime(MimeType::XML_APPLICATION); $page->set_data($xml); @@ -67,7 +67,7 @@ class XMLSitemap extends Extension "post/view/$image->id", "weekly", "0.8", - date("Y-m-d", strtotime_ex($image->posted)) + date("Y-m-d", \Safe\strtotime($image->posted)) ); } @@ -87,7 +87,7 @@ class XMLSitemap extends Extension "post/view/$image->id", "monthly", "0.6", - date("Y-m-d", strtotime_ex($image->posted)) + date("Y-m-d", \Safe\strtotime($image->posted)) ); } diff --git a/ext/static_files/main.php b/ext/static_files/main.php index f7311d93..0f05d73f 100644 --- a/ext/static_files/main.php +++ b/ext/static_files/main.php @@ -48,7 +48,7 @@ class StaticFiles extends Extension $page->add_http_header("Cache-control: public, max-age=600"); $page->add_http_header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 600) . ' GMT'); $page->set_mode(PageMode::DATA); - $page->set_data(file_get_contents_ex($filename)); + $page->set_data(\Safe\file_get_contents($filename)); $page->set_mime(MimeType::get_for_file($filename)); } } diff --git a/ext/tag_editcloud/main.php b/ext/tag_editcloud/main.php index edeb3773..f65c1d05 100644 --- a/ext/tag_editcloud/main.php +++ b/ext/tag_editcloud/main.php @@ -163,7 +163,7 @@ class TagEditCloud extends Extension } $size = sprintf("%.2f", max($row['scaled'], 0.5)); - $js = html_escape('tageditcloud_toggle_tag(this,'.json_encode_ex($full_tag).')'); //Ugly, but it works + $js = html_escape('tageditcloud_toggle_tag(this,'.\Safe\json_encode($full_tag).')'); //Ugly, but it works if (in_array($row['tag'], $image->get_tag_array())) { if ($used_first) { diff --git a/ext/tag_history/main.php b/ext/tag_history/main.php index 7f9fb246..1af6c08d 100644 --- a/ext/tag_history/main.php +++ b/ext/tag_history/main.php @@ -205,10 +205,7 @@ class TagHistory extends Extension $stored_image_id = (int)$result['image_id']; $stored_tags = $result['tags']; - $image = Image::by_id($stored_image_id); - if (!$image instanceof Image) { - throw new ImageNotFound("Error: cannot find any image with the ID = ". $stored_image_id); - } + $image = Image::by_id_ex($stored_image_id); log_debug("tag_history", 'Reverting tags of >>'.$stored_image_id.' to ['.$stored_tags.']'); // all should be ok so we can revert by firing the SetUserTags event. diff --git a/ext/tag_history/test.php b/ext/tag_history/test.php index 4c3fc084..aeca8b2a 100644 --- a/ext/tag_history/test.php +++ b/ext/tag_history/test.php @@ -10,7 +10,7 @@ class TagHistoryTest extends ShimmiePHPUnitTestCase { $this->log_in_as_admin(); $image_id = $this->post_image("tests/pbx_screenshot.jpg", "old_tag"); - $image = Image::by_id($image_id); + $image = Image::by_id_ex($image_id); // Original $this->get_page("post/view/$image_id"); diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php index 5d6e3687..8e92e985 100644 --- a/ext/tag_list/main.php +++ b/ext/tag_list/main.php @@ -235,7 +235,7 @@ class TagList extends Extension md5("tc" . $tags_min . $starts_with . VERSION) ); if (file_exists($cache_key)) { - return file_get_contents_ex($cache_key); + return \Safe\file_get_contents($cache_key); } $tag_data = $database->get_all(" @@ -288,7 +288,7 @@ class TagList extends Extension md5("ta" . $tags_min . $starts_with . VERSION) ); if (file_exists($cache_key)) { - return file_get_contents_ex($cache_key); + return \Safe\file_get_contents($cache_key); } $tag_data = $database->get_pairs(" @@ -368,7 +368,7 @@ class TagList extends Extension md5("tp" . $tags_min . VERSION) ); if (file_exists($cache_key)) { - return file_get_contents_ex($cache_key); + return \Safe\file_get_contents($cache_key); } $tag_data = $database->get_all(" diff --git a/ext/transcode/main.php b/ext/transcode/main.php index ed6f6e5c..068aa983 100644 --- a/ext/transcode/main.php +++ b/ext/transcode/main.php @@ -209,17 +209,13 @@ class TranscodeImage extends Extension if ($event->page_matches("transcode/{image_id}", method: "POST", permission: Permissions::EDIT_FILES)) { $image_id = $event->get_iarg('image_id'); - $image_obj = Image::by_id($image_id); - if (is_null($image_obj)) { - $this->theme->display_error(404, "Post not found", "No image in the database has the ID #$image_id"); - } else { - try { - $this->transcode_and_replace_image($image_obj, $event->req_POST('transcode_mime')); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/".$image_id)); - } catch (ImageTranscodeException $e) { - $this->theme->display_transcode_error($page, "Error Transcoding", $e->getMessage()); - } + $image_obj = Image::by_id_ex($image_id); + try { + $this->transcode_and_replace_image($image_obj, $event->req_POST('transcode_mime')); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/".$image_id)); + } catch (ImageTranscodeException $e) { + $this->theme->display_transcode_error($page, "Error Transcoding", $e->getMessage()); } } } @@ -382,7 +378,7 @@ class TranscodeImage extends Extension $tmp_name = shm_tempnam("transcode"); - $image = false_throws(imagecreatefromstring(file_get_contents_ex($source_name))); + $image = false_throws(imagecreatefromstring(\Safe\file_get_contents($source_name))); try { $result = false; switch ($target_mime) { diff --git a/ext/transcode_video/main.php b/ext/transcode_video/main.php index 64229dd7..20355777 100644 --- a/ext/transcode_video/main.php +++ b/ext/transcode_video/main.php @@ -103,17 +103,13 @@ class TranscodeVideo extends Extension if ($event->page_matches("transcode_video/{image_id}", method: "POST", permission: Permissions::EDIT_FILES)) { $image_id = $event->get_iarg('image_id'); - $image_obj = Image::by_id($image_id); - if (is_null($image_obj)) { - $this->theme->display_error(404, "Post not found", "No post in the database has the ID #$image_id"); - } else { - try { - $this->transcode_and_replace_video($image_obj, $event->req_POST('transcode_format')); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("post/view/".$image_id)); - } catch (VideoTranscodeException $e) { - $this->theme->display_transcode_error($page, "Error Transcoding", $e->getMessage()); - } + $image_obj = Image::by_id_ex($image_id); + try { + $this->transcode_and_replace_video($image_obj, $event->req_POST('transcode_format')); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/".$image_id)); + } catch (VideoTranscodeException $e) { + $this->theme->display_transcode_error($page, "Error Transcoding", $e->getMessage()); } } } diff --git a/ext/upload/main.php b/ext/upload/main.php index b2d620d4..c77509a6 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -45,8 +45,8 @@ class DataUploadEvent extends Event { assert(is_readable($tmpname)); $this->tmpname = $tmpname; - $this->hash = md5_file_ex($tmpname); - $this->size = filesize_ex($tmpname); + $this->hash = \Safe\md5_file($tmpname); + $this->size = \Safe\filesize($tmpname); $mime = $mime ?? MimeType::get_for_file($tmpname, get_file_ext($this->metadata["filename"]) ?? null); if (empty($mime)) { throw new UploadException("Could not determine mime type"); diff --git a/ext/upload/test.php b/ext/upload/test.php index c2093263..70f5b038 100644 --- a/ext/upload/test.php +++ b/ext/upload/test.php @@ -80,7 +80,7 @@ class UploadTest extends ShimmiePHPUnitTestCase public function testRejectHuge(): void { // FIXME: huge.dat is rejected for other reasons; manual testing shows that this works - file_put_contents("data/huge.jpg", file_get_contents_ex("tests/pbx_screenshot.jpg") . str_repeat("U", 1024 * 1024 * 3)); + file_put_contents("data/huge.jpg", \Safe\file_get_contents("tests/pbx_screenshot.jpg") . str_repeat("U", 1024 * 1024 * 3)); $e = $this->assertException(UploadException::class, function () { $this->post_image("data/huge.jpg", "test"); }); diff --git a/ext/view/main.php b/ext/view/main.php index ba8c4983..7b10f19a 100644 --- a/ext/view/main.php +++ b/ext/view/main.php @@ -34,11 +34,7 @@ class ViewPost extends Extension $query = null; } - $image = Image::by_id($image_id); - if (is_null($image)) { - $this->theme->display_error(404, "Post not found", "Post $image_id could not be found"); - return; - } + $image = Image::by_id_ex($image_id); if ($event->page_matches("post/next/{image_id}")) { $image = $image->get_next($search_terms); @@ -64,16 +60,11 @@ class ViewPost extends Extension } $image_id = $event->get_iarg('image_id'); - $image = Image::by_id($image_id); - - if (!is_null($image)) { - send_event(new DisplayingImageEvent($image)); - } else { - $this->theme->display_error(404, "Post not found", "No post in the database has the ID #$image_id"); - } + $image = Image::by_id_ex($image_id); + send_event(new DisplayingImageEvent($image)); } elseif ($event->page_matches("post/set", method: "POST")) { $image_id = int_escape($event->req_POST('image_id')); - $image = Image::by_id($image_id); + $image = Image::by_id_ex($image_id); if (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) { // currently all post metadata is string => string - in the future // we might want to have a more complex type system, but for now diff --git a/ext/view/test.php b/ext/view/test.php index cbb1e3c0..0d0d86ea 100644 --- a/ext/view/test.php +++ b/ext/view/test.php @@ -90,10 +90,11 @@ class ViewPostTest extends ShimmiePHPUnitTestCase $image_id_1 = $this->post_image("tests/favicon.png", "test"); $idp1 = $image_id_1 + 1; - $this->get_page("post/view/$idp1"); - $this->assert_title('Post not found'); - - $this->get_page('post/view/-1'); - $this->assert_title('Post not found'); + $this->assertException(ImageNotFound::class, function () use ($idp1) { + $this->get_page("post/view/$idp1"); + }); + $this->assertException(ImageNotFound::class, function () { + $this->get_page('post/view/-1'); + }); } } diff --git a/tests/phpstan.neon b/tests/phpstan.neon index 644b3d7c..d80d46f1 100644 --- a/tests/phpstan.neon +++ b/tests/phpstan.neon @@ -15,3 +15,5 @@ parameters: - STATSD_HOST - TRACE_FILE - UNITTEST +#includes: +# - ../vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon