From 2fc38b15c10e75bd9d88032a4e8cd9816ac0e55c Mon Sep 17 00:00:00 2001 From: snipe Date: Sun, 2 Aug 2026 11:55:01 +0100 Subject: [PATCH] Added test --- .../AcceptanceReportCsvFormulaEscapeTest.php | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/Feature/Reporting/AcceptanceReportCsvFormulaEscapeTest.php diff --git a/tests/Feature/Reporting/AcceptanceReportCsvFormulaEscapeTest.php b/tests/Feature/Reporting/AcceptanceReportCsvFormulaEscapeTest.php new file mode 100644 index 0000000000..86066b4e64 --- /dev/null +++ b/tests/Feature/Reporting/AcceptanceReportCsvFormulaEscapeTest.php @@ -0,0 +1,81 @@ +create(); + $asset = Asset::factory()->create(['name' => $assetName, 'company_id' => $company->id]); + + return CheckoutAcceptance::factory()->pending()->for($asset, 'checkoutable')->create(); + } + + public function test_data_rows_with_formula_prefix_are_escaped_by_default() + { + $this->seedPendingAcceptanceWithAssetNamed('=HYPERLINK("http://attacker.test","click")'); + + $body = $this->actingAs(User::factory()->superuser()->create()) + ->post(route('reports/export/unaccepted_assets')) + ->assertOk() + ->getContent(); + + $this->assertStringNotContainsString('=HYPERLINK("http://attacker.test","click")', $body); + $this->assertStringContainsString('`=HYPERLINK', $body); + } + + public function test_data_rows_with_plus_and_at_prefixes_are_escaped() + { + $this->seedPendingAcceptanceWithAssetNamed('+cmd|/c calc'); + $this->seedPendingAcceptanceWithAssetNamed('@SUM(A1:A9)'); + + $body = $this->actingAs(User::factory()->superuser()->create()) + ->post(route('reports/export/unaccepted_assets')) + ->assertOk() + ->getContent(); + + $this->assertStringContainsString('`+cmd|', $body); + $this->assertStringContainsString('`@SUM(', $body); + } + + public function test_data_rows_are_not_escaped_when_setting_disabled() + { + // Matches how the sibling exports in ReportsController behave when + // operators intentionally disable escaping. + config(['app.escape_formulas' => false]); + + $this->seedPendingAcceptanceWithAssetNamed('=SUM(A1:A9)'); + + $body = $this->actingAs(User::factory()->superuser()->create()) + ->post(route('reports/export/unaccepted_assets')) + ->assertOk() + ->getContent(); + + $this->assertStringContainsString('=SUM(A1:A9)', $body); + $this->assertStringNotContainsString('`=SUM(A1:A9)', $body); + } +}