Möchten Sie PDFs parsen?
(eliot-jones.com)- PDF-Parsing sollte auf einer klaren Reihenfolge und Struktur basieren, doch reale Dateien halten sich oft nicht an diese Vorgaben
- Bei Cross-Reference-(xref-)Zeigern und beim Finden von Offsets treten verschiedene Fehler und Inkonsistenzen auf
- In der Praxis entstehen viele Probleme durch unnötige Daten vor dem PDF-Header oder durch falsch platzierte Zeiger und Offsets
- Es gibt auch viele Fälle, in denen die xref-Tabelle selbst unklar oder fehlerhaft formatiert ist
- Deshalb implementieren große Viewer zusätzliche Logik, um auch nicht standardkonforme PDF-Dateien zu unterstützen
Ein idealer Ansatz für das PDF-Parsing
- PDF-Parsing läuft theoretisch in festen Schritten ab
- Am Dateianfang wird der Kommentar mit dem Versions-Header gesucht
- Der Cross-Reference-(xref-)Zeiger wird gefunden
- Alle Objekt-Offsets werden gesammelt
- Das trailer-Dictionary wird gefunden, um auf die gesamte Katalogstruktur zuzugreifen
Einführung in PDF-Objekte
- PDF-Objekte sind Einheiten, die Zahlen, Strings, Dictionaries und andere PDF-Elemente kapseln und speichern
- Jedes Objekt befindet sich zwischen den Markern "
obj/endobj" - Objekte sind über indirekte Referenzen (indirect reference, z. B. "16 0 R") miteinander verbunden
- Wie Objekte in der Datei verteilt sind, ist flexibel, aber einige Objekttypen müssen zwingend indirekt referenziert werden
Cross-Reference-Offsets finden
- Ein PDF enthält strukturell eine Cross-Reference-(xref-)Tabelle, die als Index für Objektpositionen dient
- Am Dateiende wird mit der Syntax "startxref" eine bestimmte Byte-Position als Zeiger angegeben
- Dieser Zeiger bestimmt die xref-Position, aber zwischen Spezifikation und realen Dateien gibt es Unterschiede. Zum Beispiel sollte der Marker "%EOF" eigentlich in der letzten Zeile stehen, in realen PDFs kann er jedoch irgendwo innerhalb der letzten 1.024 Byte auftauchen
- In realen Dateien finden sich verschiedene Abweichungen wie Formatfehler beim Zeiger (
startrefusw.) oder fehlende Zeilenumbrüche
Objekt-Offsets finden
- In der xref-Tabelle folgen auf "xref" die Startnummer des Objekts und die Anzahl der Objekte, und Offset/Generationsnummer/Status (n oder f) jedes Objekts werden zeilenweise aufgeführt
- Es kann mehrere xref-Tabellen geben, die über den /Prev-Eintrag miteinander verknüpft sind
Position des trailer-Dictionarys suchen
- Oberhalb des startxref-Markers befindet sich das trailer-Dictionary, das die wesentlichen Metadaten enthält, um das Root-Objekt zu finden
- Ausgehend vom Root-Objekt kann mit der Interpretation der gesamten Struktur begonnen werden
Die Praxis: unerwartete Probleme
-
Viele Dateien halten sich nicht an die PDF-Spezifikation, sodass sie mit einem allgemeinen Parser nur schwer verarbeitet werden können
-
Häufige Fehlschläge bei der Suche nach Cross-Reference-Zeigern
- Der Zeiger befindet sich nicht am Dateiende oder nicht innerhalb der letzten 1.024 Byte
- Tippfehler (
startrefusw.) - Ausnahmeformate
-
In einer Untersuchung von 3.977 realen PDF-Beispielen hatten etwa 0,5 % Fehler in der xref-Deklaration
PDF-Inhalt beginnt bei einem Offset ungleich 0
- Wenn sich vor dem Header unnütze Daten (junk) befinden, verschieben sich alle Byte-Offsets, wodurch die startxref-Position nicht mehr stimmt
- Offsets müssen relativ zur Header-Position neu berechnet werden, und beide Positionen müssen geprüft werden
- Das macht etwa 50 % aller Fehler aus
Der xref-Zeiger zeigt auf die Mitte der xref-Tabelle
- Der angegebene Offset kann mitten in den Inhalt der xref-Tabelle zeigen
- In 3.977 Beispielen wurde das etwa 5 Mal beobachtet
Der Zeiger liegt in der Nähe von xref
- Oft ist der Zeiger nicht exakt korrekt, sondern nur um Leerzeichen oder Zeilenumbruchzeichen direkt vor oder nach xref verschoben
Der Zeiger stimmt, aber die xref-Offsets sind falsch
- Auch die in der xref-Tabelle eingetragenen Offsets selbst können falsch sein
- Bei manchen Objekten stimmt der Wert, während andere fehlerhafte Offsets haben
Der erste Zeiger ist korrekt, aber der vorherige Offset (/Prev) ist fehlerhaft
- In vielen Fällen werden beim Bearbeiten eines PDFs im /Prev-Zeiger falsche Werte gespeichert (z. B. 0)
Das Format der xref-Tabelle ist fehlerhaft
- Es gibt viele Varianten:
"xref"und Zahlen kleben ohne Zeilenumbruch zusammen, es gibt mehr Einträge als deklarierte Objekte, oder mitten in der Tabelle befinden sich Mülldaten - Solche Fälle wurden etwa bei PdfPig vielfach als Issues gemeldet
Fazit
- Laut Spezifikation sollte PDF-Parsing in einer standardisierten Reihenfolge ablaufen, aber viele reale Dateien tun das nicht, wodurch verschiedenste Parsing-Probleme entstehen
- PDF-Viewer für den praktischen Einsatz enthalten standardmäßig Funktionen zur Unterstützung nicht standardkonformer PDFs
- Diese Zusammenfassung behandelt nur einen kleinen Teil des Parsings aus der PDF-Spezifikation (22 Seiten von insgesamt 1300 Seiten)
Noch keine Kommentare.