diff --git a/tests/64_AnlageCsvInjectionTest.php b/tests/64_AnlageCsvInjectionTest.php index 8a743a9..ca62fab 100644 --- a/tests/64_AnlageCsvInjectionTest.php +++ b/tests/64_AnlageCsvInjectionTest.php @@ -33,7 +33,10 @@ class AnlageCsvInjectionTest extends TestCase } $this->assertNotEmpty($zeile, 'Zeile mit Test-Anlage in der CSV-Ausgabe gefunden'); - $felder = explode(';', (string)$zeile); + // fputcsv() setzt Felder mit Leerzeichen in Anführungszeichen. Die Zeile + // muss daher als CSV geparst werden – ein einfaches explode(';') würde + // die Quotes als Teil des Werts mitliefern. + $felder = str_getcsv(rtrim((string)$zeile, "\r\n"), ';'); $bezeichnung = $felder[1] ?? ''; $this->assertEquals( diff --git a/tests/67_BelegXmlXsltXssTest.php b/tests/67_BelegXmlXsltXssTest.php index aa0db09..fa43c2a 100644 --- a/tests/67_BelegXmlXsltXssTest.php +++ b/tests/67_BelegXmlXsltXssTest.php @@ -52,23 +52,41 @@ class BelegXmlXsltXssTest extends TestCase ob_start(); $controller->serveFile(['id' => (string)$belegId]); - ob_get_clean(); + $body = (string)ob_get_clean(); - $headers = headers_list(); - $disposition = ''; - foreach ($headers as $header) { - if (stripos($header, 'Content-Disposition:') === 0) { - $disposition = $header; - } - } + // Der Beleg muss überhaupt ausgeliefert werden (kein 403 durch den + // Pfad-Check, kein 404) – sonst sagt die Disposition-Prüfung nichts aus. + $this->assert( + str_contains($body, 'xsl:stylesheet'), + 'serveFile() liefert den XML-Beleg aus (kein 403/404)' + ); - $this->assertNotEmpty( - $disposition, - 'Es wurde ein Content-Disposition-Header gesetzt' + // headers_list() ist unter der CLI-SAPI immer leer, der real gesetzte + // Header lässt sich hier also nicht auslesen. Geprüft wird deshalb die + // Auslieferungslogik in serveFile() selbst. + $controllerFile = __DIR__ . '/../src/Controllers/BelegController.php'; + $quelltext = (string)file_get_contents($controllerFile); + + $start = strpos($quelltext, 'function serveFile'); + $this->assert($start !== false, 'Methode serveFile() ist im BelegController vorhanden'); + + $rest = substr($quelltext, (int)$start); + $laenge = preg_match('/\n (?:public|private|protected) function /', $rest, $treffer, PREG_OFFSET_CAPTURE) + ? $treffer[0][1] + : strlen($rest); + $serveFile = substr($rest, 0, $laenge); + + $this->assert( + str_contains($serveFile, "'application/xml'") && str_contains($serveFile, "'text/xml'"), + 'serveFile() erkennt XML-MIME-Typen gesondert' ); $this->assert( - stripos($disposition, 'attachment') !== false, - "XML-Beleg wird als attachment statt inline ausgeliefert (erhalten: {$disposition})" + (bool)preg_match("/\?\s*'attachment'\s*:\s*'inline'/", $serveFile), + 'XML wird als attachment ausgeliefert, alles andere weiterhin inline' + ); + $this->assert( + (bool)preg_match("/Content-Disposition:\s*'\s*\.\s*\\\$disposition/", $serveFile), + 'Der Content-Disposition-Header nutzt die ermittelte Disposition (nicht fest inline)' ); @unlink($absPath);