From 05f8034439e528fad272ab46e3698e998fa01cf1 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 23 May 2022 16:11:28 +0100 Subject: [PATCH] Added embed support for contained HTML exports Unfortunately CSP rules will block embeds anyway. Need to either relax CSP rules on exports, or instead convert to img tags? Also cleaned up existing regexes. --- app/Entities/Tools/ExportFormatter.php | 15 ++++++--------- tests/Entity/ExportTest.php | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/Entities/Tools/ExportFormatter.php b/app/Entities/Tools/ExportFormatter.php index 99aa4536f..ed3e8d326 100644 --- a/app/Entities/Tools/ExportFormatter.php +++ b/app/Entities/Tools/ExportFormatter.php @@ -215,14 +215,13 @@ class ExportFormatter */ protected function containHtml(string $htmlContent): string { + // Replace image & embed src attributes with base64 encoded data strings $imageTagsOutput = []; - preg_match_all("/\/i", $htmlContent, $imageTagsOutput); - - // Replace image src with base64 encoded image strings + preg_match_all("/<(?:img|embed) .*?src=['\"](.*?)['\"].*?>/i", $htmlContent, $imageTagsOutput); if (isset($imageTagsOutput[0]) && count($imageTagsOutput[0]) > 0) { foreach ($imageTagsOutput[0] as $index => $imgMatch) { $oldImgTagString = $imgMatch; - $srcString = $imageTagsOutput[2][$index]; + $srcString = $imageTagsOutput[1][$index]; $imageEncoded = $this->imageService->imageUriToBase64($srcString); if ($imageEncoded === null) { $imageEncoded = $srcString; @@ -232,14 +231,13 @@ class ExportFormatter } } + // Replace any relative links with full system URL $linksOutput = []; - preg_match_all("/\/i", $htmlContent, $linksOutput); - - // Replace image src with base64 encoded image strings + preg_match_all("//i", $htmlContent, $linksOutput); if (isset($linksOutput[0]) && count($linksOutput[0]) > 0) { foreach ($linksOutput[0] as $index => $linkMatch) { $oldLinkString = $linkMatch; - $srcString = $linksOutput[2][$index]; + $srcString = $linksOutput[1][$index]; if (strpos(trim($srcString), 'http') !== 0) { $newSrcString = url($srcString); $newLinkString = str_replace($srcString, $newSrcString, $oldLinkString); @@ -248,7 +246,6 @@ class ExportFormatter } } - // Replace any relative links with system domain return $htmlContent; } diff --git a/tests/Entity/ExportTest.php b/tests/Entity/ExportTest.php index 08d092111..9debec12b 100644 --- a/tests/Entity/ExportTest.php +++ b/tests/Entity/ExportTest.php @@ -258,6 +258,24 @@ class ExportTest extends TestCase unlink($testFilePath); } + public function test_page_export_contained_html_embed_element_srcs_are_inlined() + { + $page = Page::query()->first(); + $page->html = ''; + $page->save(); + + $storageDisk = Storage::disk('local'); + $storageDisk->makeDirectory('uploads/images/gallery'); + $storageDisk->put('uploads/images/gallery/svg_test.svg', 'good'); + + $resp = $this->asEditor()->get($page->getUrl('/export/html')); + + $storageDisk->delete('uploads/images/gallery/svg_test.svg'); + + $resp->assertDontSee('http://localhost/uploads/images/gallery/svg_test.svg', false); + $resp->assertSee('', false); + } + public function test_exports_removes_scripts_from_custom_head() { $entities = [