Begrensd XRef-herstel
HotPDF kan een echte objectgraaf en paginaboom reconstrueren wanneer een PDF een ontbrekende, ongeldige of verouderde startxref-declaratie of onbruikbare xref-rijen heeft
Recovery sequence
- De normale, specs-conforme loader draait als eerste in de defaultmodus
xrrmOnFailure - Het herstel scant de bron in chunks van 1 MiB met een korte carry tussen chunks en registreert gevalideerde indirecte objecten en xref-ankers
- Markers die in een gevalideerd indirect object genest zijn, worden geweigerd, inclusief strings, commentaren, woordenboeken en binaire streamdata met tekst zoals
99 0 objofxref - Geldige xref-tabellen of -streams worden van nieuw naar oud geprobeerd via de bestaande incremental-, hybrid- en object-stream-loader
- Er worden maximaal 4.096 xref-sectie-ankers bewaard, zodat kwaadwillende markerherhaling de parsepogingen niet kan verveelvoudigen
- Als geen enkele xref-sectie een echte paginaboom oplevert, worden direct-object-offsets herbouwd en gebruiken dubbele objectnummers de meest recente fysieke definitie
- Herstel slaagt alleen als een echte Catalog, een Pages-boom en ten minste één paginablad oplosbaar zijn
Declaraties
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;
Configuratie
| Lid | Standaard | Doel |
|---|---|---|
XRefRecoveryMode | xrrmOnFailure | Schakelt herstel uit, voert het pas uit nadat normaal parsen mislukt, of forcéert het vóór het normale parsen |
XRefRecoveryMaxScanBytes | 8 GiB | Absolute maximale brongrootte die de herstelscan per chunk accepteert |
XRefRecoveryMaxObjects | 2.000.000 | Absoluut maximum aan gevalideerde indirecte-objectkandidaten dat het herstel accepteert |
ParserRecoveryEventLimit | 1,024 | Maximaal aantal gestructureerde events dat per load wordt bewaard; nul schakelt het bewaren van events uit |
Recovery information
GetLoadedXRefRecoveryInfo geeft True terug als herstel is geprobeerd en kopieert het meest recente record THPDFXRefRecoveryInfo
Statusonderscheidt succes, uitgeschakeld herstel, falen op bytelimiet, falen op objectlimiet, falen op xref-ankerlimiet en structureel falenMethodidentificeert een verplaatste xref-sectie of herbouwde direct-object-offsetsBytesScanned,CandidateObjectCount,RecoveredObjectCount,DuplicateObjectCount,RejectedCandidateCountenXRefCandidateCountmaken het begrensde werk en de herstelkwaliteit inzichtelijkSelectedXRefOffsetidentificeert de verplaatste sectie wanneer die methode slaagtDiagnosticbevat een beknopte Engelse resultaatomschrijving
Gestructureerde herstelevents
GetLoadedParserRecoveryEvents geeft een snapshot van de bewaarde eventstream in eigendom van de aanroeper terug, terwijl GetLoadedParserRecoveryEvent één invoer leest zonder een arraykopie toe te wijzen
Kindonderscheidt attempt-, policy-, limiet-, objectkandidaat-, xref-kandidaat-, geselecteerde-sectie-, herbouwde-offsets-, succes- en faaleventsFirstByteis inclusief enEndByteexclusief; beide staan op-1als er geen bronbereik bestaatObjectNumberenGenerationNumberidentificeren indirecte-objectkandidaten en gebruiken-1voor events op documentniveau of xref-ankereventsConfidenceloopt vanprcNonevia low, medium en high naar verifiedLoadedParserRecoveryEventDroppedCountrapporteert events die na de ingestelde retentielimiet zijn weggelaten, zodat het geheugen bij vijandige invoer begrensd blijft
Informatie over merge-precedentie
GetLoadedXRefMergeInfo geeft True terug wanneer laden via xref-stream of hybrid-referentie merge-status heeft aangetroffen die het rapporteren waard is
HybridRevisionCounttelt traditionele revisies die een zij-xref-stream via/XRefStmhebben bijgedragenHybridOverlapCounttelt tabelinvoeren die de xref-stream van dezelfde revisie al leverde, en die voorrang heeftOlderRevisionShadowedEntryCounttelt invoeren die zijn genegeerd omdat een nieuwere revisie dat objectnummer al definieerdeDuplicateEntryCounttelt herhaalde invoeren binnen de nieuwste non-hybrid-sectie- De twee precedentievlaggen geven aan of de bijbehorende regel daadwerkelijk is toegepast in plaats van slechts beschikbaar
Integrity information
GetLoadedXRefIntegrityInfo rapporteert de actieve free-list-keten, ongeldige verwijzingen, cycli, niet-gelinkte vrije invoeren, generatieovergangsfouten, dubbele levende definities en oudere invoeren die door de nieuwste revisie worden overschaduwd
Details van overschaduwde invoeren omvatten actieve en geweigerde invoertypes, offsets of opslagvelden, generaties en revisiediepte, met een vast detailplafond van 256 invoeren
Gereconstrueerde documenten opslaan
Een gereconstrueerd document gebruikt altijd het volledige herschrijfpad in SaveLoadedDocument, ook als er geen object is bewerkt, zodat HotPDF beschadigde sourcebytes nooit kopieert als ogend gerepareerde uitvoer
Voorbeeld
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;