diff --git a/app/Exports/PdfGenerator.php b/app/Exports/PdfGenerator.php index 0524e063f..f31d8aad0 100644 --- a/app/Exports/PdfGenerator.php +++ b/app/Exports/PdfGenerator.php @@ -90,18 +90,28 @@ class PdfGenerator $process = Process::fromShellCommandline($command); $process->setTimeout($timeout); + $cleanup = function () use ($inputHtml, $outputPdf) { + foreach ([$inputHtml, $outputPdf] as $file) { + if (file_exists($file)) { + unlink($file); + } + } + }; + try { $process->run(); } catch (ProcessTimedOutException $e) { + $cleanup(); throw new PdfExportException("PDF Export via command failed due to timeout at {$timeout} second(s)"); } if (!$process->isSuccessful()) { + $cleanup(); throw new PdfExportException("PDF Export via command failed with exit code {$process->getExitCode()}, stdout: {$process->getOutput()}, stderr: {$process->getErrorOutput()}"); } $pdfContents = file_get_contents($outputPdf); - unlink($outputPdf); + $cleanup(); if ($pdfContents === false) { throw new PdfExportException("PDF Export via command failed, unable to read PDF output file"); diff --git a/tests/Exports/PdfExportTest.php b/tests/Exports/PdfExportTest.php index 9d85c69e2..e4de87d0d 100644 --- a/tests/Exports/PdfExportTest.php +++ b/tests/Exports/PdfExportTest.php @@ -5,6 +5,7 @@ namespace Tests\Exports; use BookStack\Entities\Models\Page; use BookStack\Exceptions\PdfExportException; use BookStack\Exports\PdfGenerator; +use FilesystemIterator; use Tests\TestCase; class PdfExportTest extends TestCase @@ -128,7 +129,7 @@ class PdfExportTest extends TestCase }, PdfExportException::class); } - public function test_pdf_command_timout_option_limits_export_time() + public function test_pdf_command_timeout_option_limits_export_time() { $page = $this->entities->page(); $command = 'php -r \'sleep(4);\''; @@ -143,4 +144,19 @@ class PdfExportTest extends TestCase }, PdfExportException::class, "PDF Export via command failed due to timeout at 1 second(s)"); } + + public function test_pdf_command_option_does_not_leave_temp_files() + { + $tempDir = sys_get_temp_dir(); + $startTempFileCount = iterator_count((new FileSystemIterator($tempDir, FilesystemIterator::SKIP_DOTS))); + + $page = $this->entities->page(); + $command = 'cp {input_html_path} {output_pdf_path}'; + config()->set('exports.pdf_command', $command); + + $this->asEditor()->get($page->getUrl('/export/pdf')); + + $afterTempFileCount = iterator_count((new FileSystemIterator($tempDir, FilesystemIterator::SKIP_DOTS))); + $this->assertEquals($startTempFileCount, $afterTempFileCount); + } }