Recuperação Limitada de Referência Cruzada

O HotPDF consegue recuperar um gráfico de objetos e árvore de páginas reais quando um PDF tem uma declaração startxref em falta, inválida ou obsoleta, ou linhas xref inutilizáveis

Sequência de recuperação

  1. O carregador normal em conformidade com a norma corre primeiro no modo predefinido xrrmOnFailure
  2. A recuperação analisa a origem em fragmentos de 1 MiB com um transporte curto entre fragmentos e regista objetos indiretos validados e âncoras xref
  3. Marcadores aninhados dentro de um objeto indireto validado são rejeitados, incluindo cadeias, comentários, dicionários e dados de fluxo binário contendo texto como 99 0 obj ou xref
  4. Tabelas ou fluxos xref válidos são experimentados do mais recente para o mais antigo através do carregador incremental, híbrido e de fluxo de objetos existente
  5. No máximo 4096 âncoras de secção xref são retidas, impedindo que a repetição adversarial de marcadores multiplique as tentativas de análise
  6. Se nenhuma secção xref produzir uma árvore de páginas real, os desvios de objetos diretos são reconstruídos e os números de objeto duplicados utilizam a definição física mais recente
  7. A recuperação só é bem-sucedida quando um Catalog real, árvore de Pages e pelo menos uma folha de página são resolvidos

Declarações

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;

Configuração

MembroPredefiniçãoFunção
XRefRecoveryModexrrmOnFailureDesativa a recuperação, corre-a apenas depois de a análise normal falhar, ou força-a antes da análise normal
XRefRecoveryMaxScanBytes8 GiBTamanho máximo de origem aceite pela análise de recuperação fragmentada
XRefRecoveryMaxObjects2.000.000Número máximo de candidatos a objetos indiretos validados aceites pela recuperação
ParserRecoveryEventLimit1.024Número máximo de eventos estruturados retidos por carregamento, com zero a desativar a retenção de eventos

Informação de recuperação

GetLoadedXRefRecoveryInfo devolve True quando a recuperação foi tentada e copia o registo THPDFXRefRecoveryInfo mais recente

Eventos de recuperação estruturados

GetLoadedParserRecoveryEvents devolve um snapshot propriedade do chamador da stream de eventos retida, enquanto GetLoadedParserRecoveryEvent lê uma entrada sem alocar uma cópia do array

Informação de precedência de junção

GetLoadedXRefMergeInfo devolve True quando o carregamento de fluxo xref ou de referência híbrida encontrou estado de junção digno de relato

Informação de integridade

GetLoadedXRefIntegrityInfo reporta a cadeia de lista livre ativa, ligações inválidas, ciclos, entradas livres desligadas, erros de transição de geração, definições ativas duplicadas e entradas mais antigas sombreadas pela revisão mais recente

O detalhe sombreado inclui tipos de entrada ativos e rejeitados, desvios ou campos de armazenamento, gerações e profundidade de revisão, com um teto de detalhe fixo de 256 entradas

Gravar documentos recuperados

Um documento recuperado utiliza sempre o caminho de reescrita completa em SaveLoadedDocument, mesmo quando nenhum objeto foi editado, para que o HotPDF nunca copie bytes de origem danificados como uma saída aparentemente reparada

Exemplo

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;

APIs relacionadas