Récupération bornée des références croisées
HotPDF peut récupérer un véritable graphe d’objets et une arborescence de pages lorsqu’un PDF présente une déclaration startxref manquante, invalide ou obsolète, ou des lignes xref inutilisables
Séquence de récupération
- Le chargeur normal conforme à la spécification s’exécute d’abord dans le mode par défaut
xrrmOnFailure - La récupération balaie la source par blocs de 1 Mio avec un court report entre les blocs et enregistre les objets indirects validés ainsi que les ancres xref
- Les marqueurs imbriqués dans un objet indirect validé sont rejetés, y compris les chaînes, les commentaires, les dictionnaires et les données binaires de flux contenant du texte tel que
99 0 objouxref - Les tables ou flux xref valides sont essayés du plus récent au plus ancien via le chargeur incrémental, hybride et de flux d’objets existant
- Au plus 4 096 ancres de sections xref sont conservées, ce qui empêche la répétition adverse de marqueurs de multiplier les tentatives d’analyse
- Si aucune section xref ne produit une véritable arborescence de pages, les offsets d’objets directs sont reconstruits et les numéros d’objets en double utilisent la définition physique la plus récente
- La récupération ne réussit que lorsqu’un véritable Catalog, une arborescence Pages et au moins une feuille de page sont résolus
Déclarations
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;
Configuration
| Membre | Par défaut | Rôle |
|---|---|---|
XRefRecoveryMode | xrrmOnFailure | Désactive la récupération, ne l’exécute qu’après l’échec de l’analyse normale, ou la force avant l’analyse normale |
XRefRecoveryMaxScanBytes | 8 GiB | Maximum absolu de taille source accepté par le scan de récupération par blocs |
XRefRecoveryMaxScanBytes | 8 Gio | Taille maximale stricte de source acceptée par le balayage de récupération par blocs |
XRefRecoveryMaxObjects | 2 000 000 | Nombre maximal strict de candidats d’objets indirects validés acceptés par la récupération |
Informations de récupération
GetLoadedXRefRecoveryInfo renvoie True lorsqu’une tentative de récupération a eu lieu et copie l’enregistrement THPDFXRefRecoveryInfo le plus récent
Statusdistingue le succès, la récupération désactivée, l’échec par limite d’octets, l’échec par limite d’objets, l’échec par limite d’ancres xref et l’échec structurelMethodidentifie une section xref relocalisée ou des offsets d’objets directs reconstruitsBytesScanned,CandidateObjectCount,RecoveredObjectCount,DuplicateObjectCount,RejectedCandidateCountetXRefCandidateCountexposent le travail borné et la qualité de la récupérationSelectedXRefOffsetidentifie la section relocalisée lorsque cette méthode réussitDiagnosticcontient une description de résultat concise en anglais
Informations de précédence de fusion
GetLoadedXRefMergeInfo renvoie True lorsque le chargement de flux xref ou de références hybrides a rencontré un état de fusion à signaler
Kinddistingue les événements de tentative, de politique, de limite, de candidat objet, de candidat xref, de section sélectionnée, d’offsets reconstruits, de succès et d’échecFirstByteest inclusif etEndByteexclusif, tous deux valant-1lorsqu’aucune plage source n’existeObjectNumberetGenerationNumberidentifient les candidats d’objets indirects et valent-1pour les événements de niveau document ou d’ancre xrefConfidenceprogresse deprcNonevers des issues faible, moyenne, haute et vérifiéeLoadedParserRecoveryEventDroppedCountrapporte les événements omis après la limite de rétention configurée, en préservant une mémoire bornée face aux entrées hostiles
Informations de précédence de fusion
GetLoadedXRefMergeInfo renvoie True lorsque le chargement par flux xref ou références hybrides a rencontré un état de fusion digne d’être rapporté
HybridRevisionCountcompte les révisions traditionnelles qui ont fourni un flux xref latéral via/XRefStmHybridOverlapCountcompte les entrées de table déjà fournies par le flux xref de la même révision, qui prend précédenceOlderRevisionShadowedEntryCountcompte les entrées ignorées parce qu’une révision plus récente avait déjà défini ce numéro d’objetDuplicateEntryCountcompte les entrées répétées dans la section non hybride la plus récente- Les deux indicateurs de précédence indiquent si la règle correspondante a été appliquée plutôt que simplement disponible
Informations d’intégrité
GetLoadedXRefIntegrityInfo rapporte la chaîne de liste libre active, les liens invalides, les cycles, les entrées libres non chaînées, les erreurs de transition de génération, les définitions vivantes dupliquées et les entrées plus anciens masquées par la révision la plus récente
Le détail masqué comprend les types d’entrées actives et rejetées, les offsets ou champs de stockage, les générations et la profondeur de révision, avec un plafond de détail fixé à 256 entrées
Enregistrement des documents récupérés
Un document récupéré utilise toujours le chemin de réécriture complète dans SaveLoadedDocument, même lorsqu’aucun objet n’a été modifié, afin qu’HotPDF ne copie jamais des octets source endommagés comme une sortie apparemment réparée
Exemple
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;