¿Quieres parsear un PDF?
(eliot-jones.com)- El parseo de PDF debería funcionar con base en un orden y una estructura claros, pero en la práctica los archivos con frecuencia no siguen esta especificación
- Se producen diversos errores e inconsistencias al encontrar punteros cross-reference (xref) y offsets
- En la práctica, muchos problemas surgen por datos innecesarios antes del encabezado PDF, o por ubicaciones incorrectas de punteros y offsets
- También hay muchos casos en los que la propia tabla xref del PDF no es clara o está mal formateada
- Por eso, los principales visores implementan lógica adicional para soportar incluso archivos PDF no estándar
Enfoque ideal para el parseo de PDF
- En teoría, el parseo de PDF avanza en pasos definidos
- Buscar el comentario del encabezado de versión al inicio del archivo
- Buscar el puntero cross-reference (xref)
- Recolectar todos los offsets de objetos
- Encontrar el diccionario trailer para acceder a toda la estructura del catálogo
Introducción a los objetos PDF
- Un objeto PDF es la unidad que envuelve y almacena varios elementos del PDF, como números, cadenas y diccionarios
- Cada objeto existe entre los marcadores "
obj/endobj" - Los objetos se conectan entre sí mediante referencias indirectas (indirect reference, por ejemplo: "16 0 R")
- La forma de dividir los objetos dentro del archivo es libre, pero algunos tipos de objeto deben ser necesariamente referencias indirectas
Cómo encontrar offsets de cross-reference
- En la estructura del PDF existe una tabla cross-reference (xref), que funciona como índice de las posiciones de los objetos
- Al final del archivo, la sintaxis "startxref" indica una posición específica en bytes como puntero
- Este puntero señala la ubicación de xref, pero hay diferencias entre la especificación y los archivos reales. Por ejemplo, el marcador "%EOF" debería estar en la última línea, pero en los PDF reales puede aparecer en cualquier lugar dentro de los últimos 1,024 bytes
- En archivos reales se encuentran muchas variaciones: errores de formato del puntero (
startref, etc.), falta de saltos de línea y más
Cómo encontrar offsets de objetos
- La tabla xref sigue la secuencia "xref", número inicial de objeto y cantidad de objetos, y en cada línea se registran el offset / número de generación / estado (n o f) de cada objeto
- Puede haber varias tablas xref, o pueden estar conectadas entre sí mediante la entrada /Prev
Búsqueda de la ubicación del diccionario trailer
- Encima del marcador startxref se encuentra el diccionario trailer, que incluye los metadatos esenciales para encontrar el objeto raíz
- A partir del objeto raíz se puede empezar a interpretar toda la estructura
Entorno real: problemas inesperados
-
Hay muchos archivos que no cumplen la especificación de PDF, por lo que es difícil procesarlos con un parser común
-
Casos en los que suele fallar la búsqueda del puntero cross-reference
- El puntero no está al final del archivo ni dentro de los últimos 1,024 bytes
- Errores tipográficos (
startref, etc.) - Formatos excepcionales
-
En una investigación de 3,977 muestras reales de PDF, aproximadamente el 0.5% tenía errores en la declaración xref
El contenido PDF comienza en un offset distinto de 0
- Si hay datos basura (junk) antes del encabezado, todos los offsets de bytes se desplazan y la posición de startxref deja de coincidir
- Hay que recalcular los offsets con base en la posición del encabezado y verificar ambas ubicaciones
- Esto representa cerca del 50% de todos los errores
El puntero xref apunta al medio de la tabla xref
- El offset indicado puede incluso llevar al medio del contenido de la tabla xref
- Se encontró en unos 5 casos de 3,977 muestras
El puntero está cerca de xref
- A menudo el puntero no es exacto, pero solo está desfasado por espacios o saltos de línea justo antes o después de xref
El puntero es correcto, pero los offsets xref son incorrectos
- Los offsets registrados en la tabla xref pueden estar mal por sí mismos
- Puede que solo algunos objetos sean correctos y el resto tenga errores de offset
El primer puntero es normal, pero el offset anterior (/Prev) es extraño
- Hay muchos casos donde el puntero /Prev generado al modificar un PDF guarda un valor incorrecto (por ejemplo, 0)
El formato de la tabla xref es anormal
- Aparecen distintos casos, como
"xref"pegado a números sin salto de línea, más entradas de las que se declararon, o datos basura en medio de la tabla - Muchos de estos casos han sido reportados como issues en PdfPig y otros
Conclusión
- Según la especificación, el parseo de PDF debería seguir un orden estructurado, pero muchos archivos reales no son así, por lo que surgen diversos problemas durante el parseo
- Los visores PDF de uso real incluyen por defecto funciones para ampliar el soporte a PDF no conformes con la especificación
- Este resumen solo cubrió una pequeña parte del parseo correspondiente a la especificación PDF (22 páginas de un total de 1300)
Aún no hay comentarios.