Begrenzte Cross-Reference-Wiederherstellung
HotPDF kann einen echten Objektgraphen und Seitenbaum wiederherstellen, wenn ein PDF eine fehlende, ungültige oder veraltete startxref-Deklaration oder unbrauchbare Xref-Zeilen hat
Wiederherstellungssequenz
- Der normale spezifikationskonforme Loader läuft zuerst im Standard-
xrrmOnFailure-Modus - Die Wiederherstellung scannt die Quelle in 1-MiB-Chunks mit einem kurzen Übertrag zwischen Chunks und zeichnet validierte indirekte Objekte und Xref-Anker auf
- Marker, die innerhalb eines validierten indirekten Objekts verschachtelt sind, werden abgelehnt, einschließlich Strings, Kommentare, Wörterbücher und binäre Stream-Daten, die Text wie
99 0 objoderxrefenthalten - Gültige Xref-Tabellen oder Streams werden vom neuesten zum ältesten über den vorhandenen inkrementellen, hybriden und Objekt-Stream-Loader versucht
- Höchstens 4.096 Xref-Abschnitts-Anker werden zurückbehalten, was verhindert, dass adversarielle Marker-Wiederholung Parse-Versuche multipliziert
- Wenn kein Xref-Abschnitt einen echten Seitenbaum erzeugt, werden direkte Objekt-Offsets wieder aufgebaut und doppelte Objektnummern verwenden die neueste physische Definition
- Die Wiederherstellung gelingt nur, wenn ein echter Katalog, ein Pages-Baum und mindestens ein Seiten-Blatt auflösen
Deklarationen
type
THPDFXRefRecoveryMode = (
xrrmDisabled,
xrrmOnFailure,
xrrmForce
);
THPDFXRefRecoveryStatus = (
xrrsNotNeeded,
xrrsSucceeded,
xrrsDisabled,
xrrsScanLimitExceeded,
xrrsObjectLimitExceeded,
xrrsXRefLimitExceeded,
xrrsFailed
);
THPDFXRefRecoveryMethod = (
xrrmethodNone,
xrrmethodRelocatedSection,
xrrmethodRebuiltObjectOffsets
);
THPDFXRefMergeInfo = record
HybridRevisionCount: Integer;
HybridOverlapCount: Integer;
OlderRevisionShadowedEntryCount: Integer;
DuplicateEntryCount: Integer;
NewestRevisionPrecedenceApplied: boolean;
HybridStreamPrecedenceApplied: boolean;
end;
property XRefRecoveryMode: THPDFXRefRecoveryMode;
property XRefRecoveryMaxScanBytes: Int64;
property XRefRecoveryMaxObjects: Integer;
function GetLoadedXRefRecoveryInfo(
out Info: THPDFXRefRecoveryInfo
): boolean;
function GetLoadedXRefMergeInfo(
out Info: THPDFXRefMergeInfo
): boolean;
Konfiguration
| Member | Standard | Zweck |
|---|---|---|
XRefRecoveryMode | xrrmOnFailure | Deaktiviert die Wiederherstellung, führt sie erst nach fehlgeschlagener normaler Analyse aus, oder erzwingt sie vor der normalen Analyse |
XRefRecoveryMaxScanBytes | 8 GiB | Harte maximale Quellgröße für den segmentierten Wiederherstellungs-Scan |
XRefRecoveryMaxObjects | 2.000.000 | Harte maximale Anzahl validierter indirekter Objektkandidaten für die Wiederherstellung |
ParserRecoveryEventLimit | 1.024 | Maximale Anzahl strukturierter Ereignisse pro Ladung; null deaktiviert die Ereignisrückhaltung |
Wiederherstellungsinformationen
GetLoadedXRefRecoveryInfo gibt True zurück, wenn eine Wiederherstellung versucht wurde, und kopiert den neuesten THPDFXRefRecoveryInfo-Datensatz
Statusunterscheidet Erfolg, deaktivierte Wiederherstellung, Byte-Limit-Fehlschlag, Objekt-Limit-Fehlschlag, Xref-Anker-Limit-Fehlschlag und strukturellen FehlschlagMethodidentifiziert einen verlagerten Xref-Abschnitt oder wieder aufgebaute direkte Objekt-OffsetsBytesScanned,CandidateObjectCount,RecoveredObjectCount,DuplicateObjectCount,RejectedCandidateCountundXRefCandidateCountlegen begrenzte Arbeit und Wiederherstellungsqualität offenSelectedXRefOffsetidentifiziert den verlagerten Abschnitt, wenn diese Methode erfolgreich istDiagnosticenthält eine prägnante englische Ergebnisbeschreibung
Strukturierte Wiederherstellungsereignisse
GetLoadedParserRecoveryEvents liefert einen Snapshot des vorgehaltenen Ereignis-Streams im Eigentum des Aufrufers, während GetLoadedParserRecoveryEvent einen Eintrag liest, ohne eine Array-Kopie zu allokieren
Kindunterscheidet Versuch-, Policy-, Limit-, Objektkandidat-, XRef-Kandidat-, gewählte-Sektion-, neu-aufgebaute-Offsets-, Erfolgs- und FehlerereignisseFirstByteist inklusiv,EndByteexklusiv; beide stehen auf-1, wenn kein Quellbereich existiertObjectNumberundGenerationNumberidentifizieren Kandidaten für indirekte Objekte und verwenden-1für Dokument- oder XRef-Anker-EreignisseConfidencedurchläuftprcNonebis zu niedrigen, mittleren, hohen und verifizierten ErgebnissenLoadedParserRecoveryEventDroppedCountmeldet Ereignisse, die nach dem konfigurierten Vorhalte-Limit fortgelassen wurden, und hält so den Speicher bei feindlichen Eingaben begrenzt
Informationen zur Merge-Präzedenz
GetLoadedXRefMergeInfo gibt True zurück, wenn Xref-Stream- oder Hybrid-Referenz-Laden auf Merging-Zustand stieß, der berichtenswert ist
HybridRevisionCountzählt traditionelle Revisionen, die einen Seiten-Xref-Stream über/XRefStmbeigetragen habenHybridOverlapCountzählt Tabelleneinträge, die bereits vom Xref-Stream derselben Revision geliefert wurden, der Vorrang hatOlderRevisionShadowedEntryCountzählt Einträge, die ignoriert wurden, weil eine neuere Revision diese Objektnummer bereits definiert hatDuplicateEntryCountzählt wiederholte Einträge innerhalb des neuesten nicht-hybriden Abschnitts- Die beiden Vorrang-Flags geben an, ob die entsprechende Regel ausgeübt wurde, anstatt nur verfügbar zu sein
Integritätsinformationen
GetLoadedXRefIntegrityInfo meldet die aktive Free-List-Kette, ungültige Verweise, Zyklen, nicht verknüpfte freie Einträge, Generationsübergangs-Fehler, doppelte lebende Definitionen und ältere Einträge, die von der neuesten Revision überdeckt werden
Überdeckt-Details umfassen aktive und zurückgewiesene Eintragstypen, Offsets oder Speicherfelder, Generationen und Revisionstiefe, mit fester Detail-Obergrenze von 256 Einträgen
Speichern wiederhergestellter Dokumente
Ein wiederhergestelltes Dokument verwendet immer den vollständigen Umschreib-Pfad in SaveLoadedDocument, selbst wenn kein Objekt bearbeitet wurde, sodass HotPDF niemals beschädigte Quell-Bytes als scheinbar reparierte Ausgabe kopiert
Beispiel
var
Info: THPDFXRefRecoveryInfo;
PDF: THotPDF;
begin
PDF := THotPDF.Create(nil);
try
PDF.XRefRecoveryMode := xrrmOnFailure;
PDF.XRefRecoveryMaxScanBytes := Int64(16) * 1024 * 1024 * 1024;
PDF.XRefRecoveryMaxObjects := 3000000;
if PDF.LoadFromFile('damaged.pdf') > 0 then
begin
if PDF.GetLoadedXRefRecoveryInfo(Info) then
WriteLn(Info.Diagnostic);
PDF.SaveLoadedDocument('recovered.pdf');
end;
finally
PDF.Free;
end;
end;