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

  1. Normalan usaglašen-spec loader radi prvi u podrazumevanom režimu xrrmOnFailure režimu
  2. Oporavak skenira izvor u blokovima od 1 MiB sa kratkim prenosom između blokova i beleži validirane indirektne objekte i xref sidra
  3. 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 obj ili xref
  4. Valjane xref tabele ili tokovi se isprobaju od najnovijeg ka najstarijem kroz postojeći inkrementalni, hibridni i loader toka objekata
  5. Zadržava se najviše 4.096 sidara xref sekcija, sprečavajući da ponavljanje neprijateljskih oznaka umnožava pokušaje raščlanjivanja
  6. 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
  7. 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

ČlanPodrazumevanoUpotreba
XRefRecoveryModexrrmOnFailureOnemogućava oporavak, pokreće ga samo nakon što normalno raščlanjivanje ne uspe, ili ga nameće pre normalnog raščlanjivanja
XRefRecoveryMaxScanBytes8 GiBTvrda maksimalna veličina izvora koju prihvata skeniranje oporavka po blokovima
XRefRecoveryMaxObjects2,000,000Tvrda maksimalna količina kandidata indirektnih objekata koje oporavak prihvata
ParserRecoveryEventLimit1,024Najviš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

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

Informacije o prvenstvu spajanja

GetLoadedXRefMergeInfo vraća True kada je xref-stream ili hybrid-reference učitavanje naišlo na stanje spajanja vredno prijavljivanja

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;

Povezani API