41 lines
1.3 KiB
Python
41 lines
1.3 KiB
Python
"""Härtung der Report-Exporte: PDF-Ressourcenzugriff, HTML-Escaping, Formula-Injection."""
|
|
import io
|
|
|
|
import pytest
|
|
|
|
from app.services.report_service import _csv_safe, report_service
|
|
|
|
|
|
def test_pdf_blocks_file_attachment(tmp_path):
|
|
secret = tmp_path / "secret.txt"
|
|
secret.write_text("TOPSECRET-MARKER")
|
|
html = f'<html><body><a rel="attachment" href="file://{secret}">x</a></body></html>'
|
|
pdf = report_service.to_pdf(html)
|
|
assert b"TOPSECRET-MARKER" not in pdf
|
|
|
|
|
|
def test_pdf_blocks_remote_image():
|
|
html = '<html><body><img src="http://127.0.0.1:9/x.png"></body></html>'
|
|
assert report_service.to_pdf(html).startswith(b"%PDF")
|
|
|
|
|
|
def test_csv_safe_prefixes_formulas_only_for_strings():
|
|
assert _csv_safe('=HYPERLINK("http://x")').startswith("'=")
|
|
assert _csv_safe("@SUM(A1)").startswith("'@")
|
|
assert _csv_safe("+1").startswith("'+")
|
|
assert _csv_safe(-2.5) == "-2.5"
|
|
assert _csv_safe(None) == ""
|
|
assert _csv_safe("Normal") == "Normal"
|
|
|
|
|
|
def test_csv_and_xlsx_neutralize_formulas():
|
|
rows = [{"note": "=1+1", "hours": -1.5}]
|
|
csv_out = report_service.to_csv(rows)
|
|
assert "'=1+1" in csv_out and "-1.5" in csv_out
|
|
|
|
from openpyxl import load_workbook
|
|
wb = load_workbook(io.BytesIO(report_service.to_xlsx(rows)))
|
|
cell = wb.active["A2"]
|
|
assert cell.data_type != "f"
|
|
assert str(cell.value).startswith("'=")
|