Ответ 1
интересная проблема. Я провел какое-то исследование:
которая анализировала pdf (из исходного кода шахтеров):
def set_parser(self, parser):
"Set the document to use a given PDFParser object."
if self._parser: return
self._parser = parser
# Retrieve the information of each header that was appended
# (maybe multiple times) at the end of the document.
self.xrefs = parser.read_xref()
for xref in self.xrefs:
trailer = xref.get_trailer()
if not trailer: continue
# If there an encryption info, remember it.
if 'Encrypt' in trailer:
#assert not self.encryption
self.encryption = (list_value(trailer['ID']),
dict_value(trailer['Encrypt']))
if 'Info' in trailer:
self.info.append(dict_value(trailer['Info']))
if 'Root' in trailer:
# Every PDF file must have exactly one /Root dictionary.
self.catalog = dict_value(trailer['Root'])
break
else:
raise PDFSyntaxError('No /Root object! - Is this really a PDF?')
if self.catalog.get('Type') is not LITERAL_CATALOG:
if STRICT:
raise PDFSyntaxError('Catalog not found!')
return
если у вас возникнет проблема с EOF, будет поднято другое исключение: '' 'другая функция из источника' ''
def load(self, parser, debug=0):
while 1:
try:
(pos, line) = parser.nextline()
if not line.strip(): continue
except PSEOF:
raise PDFNoValidXRef('Unexpected EOF - file corrupted?')
if not line:
raise PDFNoValidXRef('Premature eof: %r' % parser)
if line.startswith('trailer'):
parser.seek(pos)
break
f = line.strip().split(' ')
if len(f) != 2:
raise PDFNoValidXRef('Trailer not found: %r: line=%r' % (parser, line))
try:
(start, nobjs) = map(long, f)
except ValueError:
raise PDFNoValidXRef('Invalid line: %r: line=%r' % (parser, line))
for objid in xrange(start, start+nobjs):
try:
(_, line) = parser.nextline()
except PSEOF:
raise PDFNoValidXRef('Unexpected EOF - file corrupted?')
f = line.strip().split(' ')
if len(f) != 3:
raise PDFNoValidXRef('Invalid XRef format: %r, line=%r' % (parser, line))
(pos, genno, use) = f
if use != 'n': continue
self.offsets[objid] = (int(genno), long(pos))
if 1 <= debug:
print >>sys.stderr, 'xref objects:', self.offsets
self.load_trailer(parser)
return
из wiki (спецификации pdf): Файл PDF состоит в основном из объектов, из которых существует восемь типов:
Boolean values, representing true or false Numbers Strings Names Arrays, ordered collections of objects Dictionaries, collections of objects indexed by Names Streams, usually containing large amounts of data The null object
Объекты могут быть либо прямыми (встроенными в другой объект), либо косвенными. Косвенные объекты нумеруются с номером объекта и номером поколения. Таблица индексов, называемая таблицей xref, дает смещение байта каждого косвенного объекта с начала файла. Эта конструкция обеспечивает эффективный случайный доступ к объектам в файле, а также позволяет делать небольшие изменения без перезаписи всего файла (инкрементное обновление). Начиная с версии PDF 1.5, косвенные объекты также могут быть расположены в специальных потоках, известных как потоки объектов. Этот метод уменьшает размер файлов с большим количеством небольших косвенных объектов и особенно полезен для Tagged PDF.
i thk проблема заключается в том, что ваш "поврежденный pdf" имеет несколько "корневых элементов" на странице.
Possible solution:
вы можете загружать источники и записывать `print function 'в каждом месте, где были восстановлены объекты xref, и где парсер пытался проанализировать эти объекты. можно будет определить полный стек ошибки (до появления этой ошибки).
ps: Я думаю, что это какая-то ошибка в продукте.