Source code for aeat.adapters.inbound.sanitizer._structtree
"""StructTree drop for :mod:`adapters.inbound.sanitizer`.The Tagged-PDF structure tree (``Root.StructTreeRoot``) carriesaccessibility text via ``/ActualText``, ``/Alt``, and ``/E``entries. Scrubbing the body Tj operands does not automaticallycatch these — the structure tree is a parallel surface. TheAstraZeneca contract redaction failure was rooted in this gap.The sanitiser drops the entire StructTreeRoot rather than walkingit. Drop > scrub: a missed key is a leak; lost accessibilitymetadata in a regression-test fixture is harmless. The:class:`SanitizationWarning` ``structtree_dropped_lossy`` recordsthe trade-off so callers know the fixture is no longerscreen-reader-equivalent to the source."""from__future__importannotationsfrompikepdfimportPdffrom._recordsimportSanitizationWarning,ScrubbedSurface
[docs]defdrop_struct_tree(pdf:Pdf)->tuple[ScrubbedSurface,tuple[SanitizationWarning,...]]:"""Removes ``Root.StructTreeRoot`` if present. Args: pdf: An open PDF whose StructTree should be wiped. Returns: A 2-tuple of (counter, warnings). The counter is a :class:`ScrubbedSurface` that is zero when the tree was absent and one when it was dropped. Warnings carry :class:`SanitizationWarning` ``structtree_dropped_lossy`` when the tree was present so callers see the lossy step in the audit log. """warnings:tuple[SanitizationWarning,...]=()if"/StructTreeRoot"notinpdf.Root:returnScrubbedSurface(surface="structtree_dropped",count=0),warningsdelpdf.Root["/StructTreeRoot"]# MarkInfo declares the document is structured; lying about it# after dropping the tree is dishonest, so wipe the marker too.if"/MarkInfo"inpdf.Root:delpdf.Root["/MarkInfo"]warnings=(SanitizationWarning(code="structtree_dropped_lossy",detail="Source PDF carried a Tagged-PDF structure tree; the sanitiser ""dropped it wholesale to avoid leaking accessibility text.",),)returnScrubbedSurface(surface="structtree_dropped",count=1),warnings