Module optionnel · pdftoolkit/pdf-reader 0.1.7

English | Français

Le lecteur analyse des octets PDF externes. Cette documentation décrit les protections implémentées et les scénarios couverts par les tests du projet. Elle ne constitue pas un audit externe ni une garantie d'absence de vulnérabilité. Le périmètre inclut la syntaxe, la résolution des objets, les révisions, les pages et les filtres pris en charge.

Surfaces contrôlées

Surface Contrôles et tests
Source Header PDF 1.0–1.7 au début des bytes, footer final borné, refus des sources dépassant la limite. Aucun chargement de chemin ou d'URL par le lecteur.
Syntaxe Longueurs des tokens, profondeur et nombre de valeurs ; échappements des noms et chaînes ; tableaux et dictionnaires bornés ; refus des clés dupliquées et des nombres hors plage.
Curseurs Chaque vue possède des bornes ; les lectures et déplacements hors vue sont refusés. Les objets comprimés sont analysés dans des tranches séparées.
Xref Offsets, générations, types et plages vérifiés ; champs big endian sans dépassement d'entier ; sous-sections et /Index sans chevauchement.
Révisions Chaîne /Prev bornée et cycles détectés ; les entrées récentes, y compris libres, masquent les anciennes. Une génération périmée se résout à null.
Objets Identifiant réel comparé à l'entrée xref ; chargements récursifs bornés et cycles de chargement détectés ; caches propres au document.
Arbre de pages Parcours avec pile explicite ; limites propres de profondeur, de nœuds et de feuilles ; refus des cycles, descendants répétés, comptes incohérents et liens Parent incorrects.
Héritage Types des ressources, rectangles et rotations vérifiés ; quatre entrées héritables seulement ; ressources locales remplaçant les valeurs héritées sans fusion ; rotation multiple de 90.
Contenus de page Page liée à son document source ; nombre de flux borné avant résolution du tableau ; chaque élément doit désigner un flux ; aucun héritage, décodage ou interprétation automatique.
Streams Étendue déterminée exclusivement par /Length. Les marqueurs de fin contenus dans les données binaires ne découpent pas le flux. Les longueurs indirectes utilisent le résolveur borné.
Données conservées Budget cumulé des noms, chaînes et octets encodés, contrôlé avant leur conservation ; des vues répétées ou chevauchantes ne peuvent pas multiplier ces copies sans plafond.
ObjStm Contrôle de /N, /First, numéros et offsets ; une valeur par tranche ; validation du numéro désigné par l'index xref ; génération zéro et longueur non comprimée.
Décompression Limite sur chaque sortie, budget cumulé sur toutes les étapes et longueur de chaîne de filtres ; décompression Flate progressive ; refus des données tronquées et des lignes de prédicteur invalides.
Mécanismes externes Pas d'exécution d'actions PDF ou JavaScript. Le décodage des streams /F, /FFilter ou /FDecodeParms externes est refusé.
Écriture Références et streams externes refusent leur sérialisation sans import et remappage ; aucun fichier de sortie n'est ouvert par le lecteur.

Les tests ReadingSyntaxTest, ReadingFiltersTest, ReadingDocumentTest, ReadingFileStructureTest, ReadingRetentionTest et ReadingPagesTest exercent ces frontières. Les cinq fixtures externes proviennent d'un générateur pypdf et d'une transformation qpdf, indépendants du writer PHP. Les deux fixtures de pages ajoutent un arbre à plusieurs niveaux, des attributs hérités ou locaux et des tableaux de contenus directs ou indirects, y compris des données binaires. Leur reproduction vérifie les bytes, les lectures strictes et les résultats structurels attendus. Une bonne lecture de ces fixtures ne démontre pas la conformité à tous les PDF possibles.

Limites par défaut

Propriété de ReaderLimits Plafond
maxFileBytes 64 MiB de source.
maxDepth 64 niveaux de syntaxe ou de chargement indirect.
maxTokenBytes 1 MiB par token ; borne également la recherche du footer.
maxContainerEntries 100 000 entrées dans un conteneur.
maxObjects 100 000 pour le plafond d'objets et la borne des numéros structuraux.
maxCrossReferenceEntries 200 000 entrées cumulées sur les révisions.
maxRevisions 64 sections dans la chaîne /Prev.
maxDecodedStreamBytes 64 MiB pour une sortie de décodage.
maxTotalDecodedBytes 128 MiB cumulés sur les étapes de décodage.
maxFilters 16 filtres dans une chaîne.
maxParsedValues 500 000 valeurs syntaxiques cumulées.
maxRetainedBytes 128 MiB cumulés pour les noms, chaînes et octets de streams conservés.

Le budget décodé compte les sorties intermédiaires, par exemple la sortie Flate puis la sortie du prédicteur. Les flux xref et les flux d'objets utilisent le même budget que les autres flux. Un accès au résultat déjà décodé dans le cache de ReadDocument ne déclenche pas un nouveau décodage.

Ces plafonds sont des limites de travail, pas une promesse sur le maximum de mémoire PHP consommée. La source, les objets, les dictionnaires et les caches occupent de la mémoire supplémentaire. Un décodeur natif peut aussi produire une tranche temporaire avant son contrôle. Les valeurs par défaut doivent être adaptées au budget mémoire et aux quotas de l'application.

Les opérations de pages ajoutent leurs plafonds : PageTreeLimits autorise par défaut 64 niveaux, 100 000 nœuds et 100 000 pages ; PageContentLimits autorise 1 024 flux par page. Ces compteurs appartiennent à une opération. Les objets chargés et les octets décodés restent soumis aux budgets cumulatifs du même ReadDocument. Consulter le guide des pages pour les configurer explicitement.

Responsabilités de l'application

L'application choisit et autorise l'origine des bytes. Elle doit borner leur acquisition avant de construire FileBytes, notamment pour un upload ou une réponse réseau. maxFileBytes est contrôlé lorsque les bytes sont déjà fournis au lecteur. Il ne contrôle pas le téléchargement ou l'ouverture d'un fichier réalisés en amont.

Le lecteur ne supprime pas les actions, pièces jointes ou autres objets potentiellement actifs du PDF. Leur existence est conservée comme donnée. Présenter ou redistribuer ensuite le fichier original reste une décision de l'application ; la réussite de la lecture n'est pas une certification que le document peut être ouvert sans risque par n'importe quel logiciel.

La résolution est à la demande. L'ouverture contrôle le catalogue et les xref, mais ne visite pas tous les objets ni toutes les ressources. Un défaut dans un objet non encore chargé peut être signalé lors d'un accès ultérieur. Le lecteur ne répare pas les fichiers endommagés et refuse les mécanismes non pris en charge, notamment le chiffrement et les références hybrides.

Les diagnostics et valeurs extraites ne doivent pas être envoyés dans une page HTML sans échappement ni publiés sans contrôle d'accès. Les données contenues dans les dictionnaires, noms et chaînes proviennent du document. L'application décide de ce qu'elle peut journaliser ou présenter.

Vérifications et dépendances

La CI exécute les tests, l'analyse statique et le contrôle de format sur PHP 8.3, 8.4 et 8.5. composer audit --locked vérifie les avis disponibles pour les dépendances verrouillées ; ce contrôle ne constitue pas un audit du code du lecteur et dépend des informations connues au moment de son exécution.

PHP, zlib, le serveur, les outils de validation et les logiciels ouvrant les PDF ont leurs propres surfaces de sécurité, hors du périmètre des tests de cette bibliothèque.

Signalements privés · Architecture

Source de ce guide au commit documenté ↗