Bounded Cross-Reference Recovery
HotPDF može da oporavi stvarni graf objekata i stablo stranica kada PDF ima deklaraciju startxref koja nedostaje, nevažeća je ili je zastarela, ili neupotrebljive xref redove
Sekvenca oporavka
- Normalan usaglašen-spec loader radi prvi u podrazumevanom režimu
xrrmOnFailurerežimu - Oporavak skenira izvor u blokovima od 1 MiB sa kratkim prenosom između blokova i beleži validirane indirektne objekte i xref sidra
- Oznake ugnježdene unutar validiranog indirektnog objekta se odbacuju, uključujući stringove, komentare, rečnike i binarne podatke toka koji sadrže tekst kao što su
99 0 objilixref - Valjane xref tabele ili tokovi se isprobaju od najnovijeg ka najstarijem kroz postojeći inkrementalni, hibridni i loader toka objekata
- Zadržava se najviše 4.096 sidara xref sekcija, sprečavajući da ponavljanje neprijateljskih oznaka umnožava pokušaje raščlanjivanja
- Ako nijedna xref sekcija ne proizvede stvarno stablo stranica, ofseti direktnih objekata se ponovo izgrađuju, a duplikati brojeva objekata koriste najnoviju fizičku definiciju
- Oporavak uspeva samo kada se razreši stvarni Catalog, stablo Pages i barem jedan list stranice
Deklaracije
type
THPDFXRefRecoveryMode = (
xrrmDisabled,
xrrmOnFailure,
xrrmForce
);
THPDFXRefRecoveryStatus = (
xrrsNotNeeded,
xrrsSucceeded,
xrrsDisabled,
xrrsScanLimitExceeded,
xrrsObjectLimitExceeded,
xrrsXRefLimitExceeded,
xrrsFailed
);
THPDFXRefRecoveryMethod = (
xrrmethodNone,
xrrmethodRelocatedSection,
xrrmethodRebuiltObjectOffsets
);
THPDFParserRecoveryConfidence = (
prcNone,
prcLow,
prcMedium,
prcHigh,
prcVerified
);
THPDFParserRecoveryEvent = record
Kind: THPDFParserRecoveryEventKind;
Confidence: THPDFParserRecoveryConfidence;
FirstByte: Int64;
EndByte: Int64;
ObjectNumber: Integer;
GenerationNumber: Integer;
Message: AnsiString;
end;
THPDFXRefMergeInfo = record
HybridRevisionCount: Integer;
HybridOverlapCount: Integer;
OlderRevisionShadowedEntryCount: Integer;
DuplicateEntryCount: Integer;
NewestRevisionPrecedenceApplied: boolean;
HybridStreamPrecedenceApplied: boolean;
end;
property XRefRecoveryMode: THPDFXRefRecoveryMode;
property XRefRecoveryMaxScanBytes: Int64;
property XRefRecoveryMaxObjects: Integer;
property ParserRecoveryEventLimit: Integer;
property LoadedParserRecoveryEventCount: Integer;
property LoadedParserRecoveryEventDroppedCount: Integer;
function GetLoadedXRefRecoveryInfo(
out Info: THPDFXRefRecoveryInfo
): boolean;
function GetLoadedParserRecoveryEvents:
THPDFParserRecoveryEventArray;
function GetLoadedParserRecoveryEvent(
Index: Integer;
out EventInfo: THPDFParserRecoveryEvent
): boolean;
function GetLoadedXRefMergeInfo(
out Info: THPDFXRefMergeInfo
): boolean;
function GetLoadedXRefIntegrityInfo(
out Info: THPDFXRefIntegrityInfo
): boolean;
Konfiguracija
| Član | Podrazumevano | Upotreba |
|---|---|---|
XRefRecoveryMode | xrrmOnFailure | Onemogućava oporavak, pokreće ga samo nakon što normalno raščlanjivanje ne uspe, ili ga nameće pre normalnog raščlanjivanja |
XRefRecoveryMaxScanBytes | 8 GiB | Tvrda maksimalna veličina izvora koju prihvata skeniranje oporavka po blokovima |
XRefRecoveryMaxObjects | 2,000,000 | Tvrda maksimalna količina kandidata indirektnih objekata koje oporavak prihvata |
ParserRecoveryEventLimit | 1,024 | Najviše strukturiranih događaja zadržano za jedno učitavanje; nula onemogućava zadržavanje događaja |
Informacije o oporavku
GetLoadedXRefRecoveryInfo vraća True kada je oporavak pokušan i kopira najnoviji zapis THPDFXRefRecoveryInfo record
Statusrazlikuje uspeh, onemogućen oporavak, neuspeh zbog limita bajtova, neuspeh zbog limita objekata, neuspeh zbog limita xref sidara i strukturni neuspehMethodidentifikuje premeštenu xref sekciju ili ponovo izgrađene ofsete direktnih objekataBytesScanned,CandidateObjectCount,RecoveredObjectCount,DuplicateObjectCount,RejectedCandidateCountiXRefCandidateCountizlažu ograničeni rad i kvalitet oporavkaSelectedXRefOffsetidentifikuje premeštenu sekciju kada ta metoda uspeDiagnosticsadrži koncisan engleski opis rezultata
Informacije o prioritetu spajanja
GetLoadedParserRecoveryEvents vraća snapshot zadržanog toka događaja u vlasništvu pozivaoca, dok GetLoadedParserRecoveryEvent čita jedan unos bez alokacije kopije niza
Kindbroji tradicionalne revizije koje su doprinele bočni xref tok krozFirstByteje uključiv aEndByteje isključiv, oba se postavljaju na-1kada izvorni opseg ne postojiObjectNumberiGenerationNumberidentifikuju kandidate indirektnih objekata i koriste-1za događaje na nivou dokumenta ili xref sidraConfidencenapreduje odprcNonekroz nizak, srednji, visok i verifikovan ishodLoadedParserRecoveryEventDroppedCountprijavljuje događaje izostavljene nakon konfigurisanog limita zadržavanja, čuvajući ograničenu memoriju na neprijateljskim ulazima
Informacije o prvenstvu spajanja
GetLoadedXRefMergeInfo vraća True kada je xref-stream ili hybrid-reference učitavanje naišlo na stanje spajanja vredno prijavljivanja
HybridRevisionCountbroji tradicionalne revizije koje su doprinele bočni xref stream kroz/XRefStmHybridOverlapCountbroji unose tabele već dostavljene xref tokom iste revizije, koji imaju prioritetOlderRevisionShadowedEntryCountbroji unose ignorisane jer je novija revizija već definisala taj broj objektaDuplicateEntryCountbroji ponovljene unose unutar najnovije nehibridne sekcije- Dve zastavice prioriteta navode da li je odgovarajuće pravilo primenjeno, a ne samo dostupno
Snimanje oporavljenih dokumenata
GetLoadedXRefIntegrityInfo, čak i kada nijedan objekat nije izmenjen, tako da HotPDF nikada ne kopira oštećene bajtove izvora kao navodno popravljen izlaz
Zasenjeni detalj uključuje aktivne i odbačene tipove unosa, pomeraje ili polja skladištenja, generacije i dubinu revizije, sa fiksnim plafonom od 256 unosa detalja
Čuvanje oporavljenih dokumenata
Oporavljeni dokument uvek koristi putanju kompletnog prepisivanja u SaveLoadedDocument, čak i kada nijedan objekat nije menjen, tako da HotPDF nikada ne kopira oštećene izvorne bajtove kao naizgled popravljen izlaz
Primer
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;