Recuperación acotada de referencias cruzadas
HotPDF puede recuperar un grafo de objetos real y un árbol de páginas cuando un PDF tiene una declaración startxref ausente, no válida o obsoleta, o filas xref inutilizables
Secuencia de recuperación
- El cargador normal conforme a la especificación se ejecuta primero en el modo predeterminado
xrrmOnFailure - La recuperación explora el origen en bloques de 1 MiB con un acarreo corto entre bloques y registra objetos indirectos validados y anclajes xref
- Los marcadores anidados dentro de un objeto indirecto validado se rechazan, incluidos strings, comentarios, diccionarios y datos binarios de flujo que contienen texto como
99 0 objoxref - Las tablas o flujos xref válidos se prueban del más nuevo al más antiguo a través del cargador incremental, híbrido y de flujo de objetos existente
- Se retienen como máximo 4096 anclajes de sección xref, lo que evita que la repetición adversaria de marcadores multiplique los intentos de análisis
- Si ninguna sección xref produce un árbol de páginas real, se reconstruyen los desplazamientos de objetos directos y los números de objeto duplicados usan la definición física más reciente
- La recuperación solo tiene éxito cuando se resuelven un Catalog real, un árbol de Pages y al menos una hoja de página
Declaraciones
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;
Configuración
| Miembro | Predeterminado | Propósito |
|---|---|---|
XRefRecoveryMode | xrrmOnFailure | Deshabilita la recuperación, la ejecuta solo cuando el análisis normal falla, o la fuerza antes del análisis normal |
XRefRecoveryMaxScanBytes | 8 GiB | Tamaño máximo duro del fuente aceptado por el escaneo de recuperación por trozos |
XRefRecoveryMaxObjects | 2,000,000 | Máximo duro de candidatos a objeto indirecto validados que acepta la recuperación |
ParserRecoveryEventLimit | 1,024 | Máximo de eventos estructurados retenidos por una carga; cero deshabilita la retención de eventos |
Información de recuperación
GetLoadedXRefRecoveryInfo devuelve True cuando se intentó la recuperación y copia el registro THPDFXRefRecoveryInfo más reciente
Statusdistingue entre éxito, recuperación deshabilitada, fallo por límite de bytes, fallo por límite de objetos, fallo por límite de anclajes xref y fallo estructuralMethodidentifica una sección xref relocalizada o desplazamientos de objetos directos reconstruidosBytesScanned,CandidateObjectCount,RecoveredObjectCount,DuplicateObjectCount,RejectedCandidateCountyXRefCandidateCountexponen el trabajo acotado y la calidad de la recuperaciónSelectedXRefOffsetidentifica la sección relocalizada cuando ese método tiene éxitoDiagnosticcontiene una descripción concisa del resultado en inglés
Eventos de recuperación estructurados
GetLoadedParserRecoveryEvents devuelve una instantánea propiedad del llamador del stream de eventos retenido, mientras que GetLoadedParserRecoveryEvent lee una entrada sin asignar una copia de array
Kinddistingue eventos de intento, política, límite, candidato a objeto, candidato a xref, sección seleccionada, offsets reconstruidos, éxito y falloFirstBytees inclusivo yEndByteexcluyente, y ambos se establecen a-1cuando no existe rango de origenObjectNumberyGenerationNumberidentifican candidatos a objeto indirecto y usan-1para eventos de nivel de documento o de ancla xrefConfidenceprogresa deprcNonea resultados bajo, medio, alto y verificadoLoadedParserRecoveryEventDroppedCountinforma de los eventos omitidos tras el límite de retención configurado, preservando una memoria acotada ante entradas hostiles
Información de precedencia de fusión
GetLoadedXRefMergeInfo devuelve True cuando la carga por flujo xref o referencia híbrida encontró estado de fusión digno de informe
HybridRevisionCountcuenta las revisiones tradicionales que aportaron un flujo xref lateral mediante/XRefStmHybridOverlapCountcuenta las entradas de tabla ya suministradas por el flujo xref de la misma revisión, que tiene precedenciaOlderRevisionShadowedEntryCountcuenta las entradas ignoradas porque una revisión más nueva ya definía ese número de objetoDuplicateEntryCountcuenta las entradas repetidas dentro de la sección no híbrida más reciente- Los dos indicadores de precedencia indican si la regla correspondiente se aplicó en lugar de estar simplemente disponible
Información de integridad
GetLoadedXRefIntegrityInfo informa de la cadena activa de listas libres, los enlaces no válidos, los ciclos, las entradas libres sin enlazar, los errores de transición de generación, las definiciones vivas duplicadas y las entradas anteriores ocultadas por la revisión más reciente
El detalle sombreado incluye tipos de entrada activos y rechazados, offsets o campos de almacenamiento, generaciones y profundidad de revisión, con un techo fijo de 256 entradas de detalle
Guardado de documentos recuperados
Un documento recuperado siempre usa la ruta de reescritura completa en SaveLoadedDocument, incluso cuando no se editó ningún objeto, de modo que HotPDF nunca copia bytes de origen dañados como una salida aparentemente reparada
Ejemplo
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;