Explorar el Código

PDF : une bibliothèque manquante autre que cryptography ne fait plus dire « protégé »

pypdf lève la même DependencyError quand il manque brotli (PDF compressés
en Brotli, encore rares). prepare_pdf en faisait « Ce PDF est protégé… »
et journalisait une « bibliothèque de déchiffrement » manquante, à tort.
Le message « protégé » est maintenant réservé à l'erreur qui cite
cryptography ; les autres donnent un message neutre, avec un WARNING qui
nomme la bibliothèque manquante.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Johnounet hace 1 día
padre
commit
3ac358c49a
Se han modificado 2 ficheros con 14 adiciones y 3 borrados
  1. 5 3
      bot/pdf_files.py
  2. 9 0
      tests/test_attachments_prep.py

+ 5 - 3
bot/pdf_files.py

@@ -37,9 +37,11 @@ def prepare_pdf(name: str, data: bytes, max_pages: int) -> ImageData:
         pages = len(reader.pages)
     except PdfError:
         raise
-    except DependencyError as exc:  # chiffrement AES sans la bibliothèque cryptography : à corriger côté serveur
-        logger.warning("PDF %s chiffré illisible faute de bibliothèque de déchiffrement : %s", name, exc)
-        raise PdfError("Ce PDF est protégé et je ne peux pas l'ouvrir pour le moment.")
+    except DependencyError as exc:  # bibliothèque manquante sur le serveur : à corriger par l'administrateur
+        logger.warning("PDF %s illisible faute de bibliothèque : %s", name, exc)
+        if "cryptography" in str(exc):  # chiffrement AES-256 ; brotli (compression rare) lève la même erreur
+            raise PdfError("Ce PDF est protégé et je ne peux pas l'ouvrir pour le moment.")
+        raise PdfError("Je ne peux pas lire ce PDF pour le moment.")
     except Exception as exc:  # fichier abîmé ou pas un PDF : pypdf lève des erreurs très variées
         logger.info("PDF %s illisible : %s", name, exc)
         raise PdfError("Je n'arrive pas à lire ce PDF.")

+ 9 - 0
tests/test_attachments_prep.py

@@ -310,6 +310,15 @@ class PreparePdfTest(unittest.TestCase):
         self.assertIn("protégé", ctx.exception.user_message)
         self.assertIn("cryptography", logs.output[0])
 
+    def test_missing_other_library(self):
+        # Une autre bibliothèque manquante (brotli : compression rare) ne fait pas croire à un PDF protégé.
+        error = pdf_files.DependencyError("brotli is required for BrotliDecode. Install it with: pip install pypdf[brotli]")
+        with mock.patch.object(pdf_files, "PdfReader", side_effect=error), \
+                self.assertLogs("chatbot.pdf", "WARNING") as logs, self.assertRaises(PdfError) as ctx:
+            prepare_pdf("compressé.pdf", b"%PDF", max_pages=3)
+        self.assertNotIn("protégé", ctx.exception.user_message)
+        self.assertIn("brotli", logs.output[0])
+
     def test_not_a_pdf(self):
         for data in (b"", b"bonjour, ceci n'est pas un PDF", encode(Image.new("RGB", (50, 50)), "PNG")):
             with self.subTest(data=data[:10]), self.assertLogs("chatbot.pdf", "INFO"), \