Обмежене відновлення перехресних посилань
HotPDF може відновити реальний граф об'єктів і дерево сторінок, коли PDF має відсутнє, некоректне або застаріле оголошення startxref або непридатні рядки xref
Послідовність відновлення
- Звичайний завантажувач, що відповідає специфікації, запускається першим у стандартному режимі
xrrmOnFailure - Відновлення сканує джерело блоками по 1 MiB із коротким перенесенням між блоками та записує перевірені непрямі об'єкти й прив'язки xref
- Маркери, вкладені у перевірений непрямий об'єкт, відхиляються, включно з рядками, коментарями, словниками та бінарними потоковими даними, що містять текст на кшталт
99 0 objабоxref - Коректні таблиці чи потоки xref випробовуються від найновіших до найстаріших через наявний інкрементальний, гібридний завантажувач об'єктних потоків
- Зберігається щонайбільше 4 096 прив'язок розділів xref, що запобігає множенню спроб парсингу через ворожі повторення маркерів
- Якщо жоден розділ xref не створює реального дерева сторінок, зміщення прямих об'єктів відбудовуються, а дубльовані номери об'єктів використовують найновіше фізичне визначення
- Відновлення завершується успішно лише тоді, коли розв'язуються реальні Catalog, дерево Pages і щонайменше один лист сторінки
Оголошення
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;
Конфігурація
| Член | Стандарт | Призначення |
|---|---|---|
XRefRecoveryMode | xrrmOnFailure | Вимикає відновлення, запускає його лише після невдачі звичайного парсингу або примусово запускає перед звичайним парсингом |
XRefRecoveryMaxScanBytes | 8 GiB | Жорсткий максимальний розмір джерела, прийнятий блоковим скануванням відновлення |
XRefRecoveryMaxObjects | 2 000 000 | Жорсткий максимум перевірених кандидатів непрямих об'єктів, прийнятих відновленням |
ParserRecoveryEventLimit | 1,024 | Максимум структурованих подій, що зберігаються для одного завантаження; нуль вимикає збереження подій |
Інформація про відновлення
GetLoadedXRefRecoveryInfo повертає True, коли відновлення було спробовано, і копіює найновіший запис THPDFXRefRecoveryInfo
Statusрозрізняє успіх, вимкнене відновлення, невдачу через ліміт байтів, невдачу через ліміт об'єктів, невдачу через ліміт прив'язок xref та структурну невдачуMethodідентифікує переміщений розділ xref або відбудовані зміщення прямих об'єктівBytesScanned,CandidateObjectCount,RecoveredObjectCount,DuplicateObjectCount,RejectedCandidateCountтаXRefCandidateCountвідкривають обмежену роботу та якість відновленняSelectedXRefOffsetідентифікує переміщений розділ, коли цей метод завершується успішноDiagnosticмістить стислий англійський опис результату
Структуровані події відновлення
GetLoadedParserRecoveryEvents повертає належний викликачу знімок збереженого потоку подій, тоді як GetLoadedParserRecoveryEvent читає один запис без розподілу копії масиву
Kindрозрізняє події спроби, політики, ліміту, кандидата об'єкта, кандидата xref, вибраного розділу, відбудованих зміщень, успіху та невдачіFirstByteє включним, аEndByte— виключним; обидва мають значення-1, коли діапазон джерела не існуєObjectNumberіGenerationNumberідентифікують кандидатів непрямих об'єктів і використовують-1для подій рівня документа чи якоря xrefConfidenceпрогресує відprcNoneкрізь низький, середній, високий і верифікований результатиLoadedParserRecoveryEventDroppedCountповідомляє події, пропущені після налаштованої межі збереження, зберігаючи обмежену пам'ять на ворожих входах
Інформація про пріоритет злиття
GetLoadedXRefMergeInfo повертає True, коли завантаження потоку xref або гібридного посилання зустріло стан злиття, вартий звітування
HybridRevisionCountпідраховує традиційні редакції, що внесли бічний потік xref через/XRefStmHybridOverlapCountпідраховує записи таблиці, уже надані потоком xref тієї самої редакції, що має пріоритетOlderRevisionShadowedEntryCountпідраховує записи, проігноровані, оскільки новіша редакція вже визначила цей номер об'єктаDuplicateEntryCountпідраховує повторні записи в межах найновішого негібридного розділу- Два прапорці пріоритету вказують, чи відповідне правило було застосовано, а не лише доступне
Інформація про цілісність
GetLoadedXRefIntegrityInfo повідомляє активний ланцюг вільного списку, недійсні посилання, цикли, неприв'язані вільні записи, помилки переходу поколінь, дублікати живих визначень і старіші записи, затінені найновішою редакцією
Деталі затінення включають активні та відхилені типи записів, зміщення або поля сховища, покоління та глибину редакції, зі фіксованою стелею деталізації в 256 записів
Збереження відновлених документів
Відновлений документ завжди використовує шлях повного перезапису в SaveLoadedDocument, навіть коли жоден об'єкт не було відредаговано, тож HotPDF ніколи не копіює пошкоджені вихідні байти як нібито відремонтований вивід
Приклад
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;