Просмотр исходного кода

Fichiers .txt : lecture du « Unicode » du Bloc-notes

Un fichier enregistré en « Unicode » par le Bloc-notes (UTF-16) contient
des octets nuls et était refusé comme « pas du texte lisible ». Les BOM
FF FE et FE FF sont maintenant détectés pour décoder le fichier en
UTF-16 ; les octets nuls ne sont plus recherchés qu'après décodage, et
un vrai fichier binaire reste refusé.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Johnounet 4 дней назад
Родитель
Сommit
2134a4c1c6
2 измененных файлов с 18 добавлено и 7 удалено
  1. 16 7
      bot/text_files.py
  2. 2 0
      changelog.txt

+ 16 - 7
bot/text_files.py

@@ -2,6 +2,8 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
+import codecs
+
 TEXT_EXTENSIONS = (".txt",)
 TEXT_EXTENSIONS = (".txt",)
 # Taille maximale d'un fichier .txt (environ 25 000 tokens, pour limiter le coût d'un message).
 # Taille maximale d'un fichier .txt (environ 25 000 tokens, pour limiter le coût d'un message).
 TEXT_FILE_MAX_BYTES = 100_000
 TEXT_FILE_MAX_BYTES = 100_000
@@ -16,14 +18,21 @@ class TextFileError(Exception):
 
 
 
 
 def decode_text_file(data: bytes) -> str:
 def decode_text_file(data: bytes) -> str:
-    """Décode le contenu d'un fichier .txt (UTF-8, sinon Windows-1252)."""
-    if b"\x00" in data:
+    """Décode le contenu d'un fichier .txt (UTF-16 avec BOM, UTF-8, sinon Windows-1252)."""
+    if data.startswith((codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE)):
+        # « Unicode » du Bloc-notes : deux octets par caractère, dont beaucoup de \x00.
+        try:
+            text = data.decode("utf-16")
+        except UnicodeDecodeError:
+            raise TextFileError("Ce fichier ne contient pas du texte lisible.")
+    else:
+        try:
+            text = data.decode("utf-8-sig")
+        except UnicodeDecodeError:
+            # Fichiers enregistrés par d'anciens éditeurs Windows (Bloc-notes, etc.).
+            text = data.decode("cp1252", errors="replace")
+    if "\x00" in text:
         raise TextFileError("Ce fichier ne contient pas du texte lisible.")
         raise TextFileError("Ce fichier ne contient pas du texte lisible.")
-    try:
-        text = data.decode("utf-8-sig")
-    except UnicodeDecodeError:
-        # Fichiers enregistrés par d'anciens éditeurs Windows (Bloc-notes, etc.).
-        text = data.decode("cp1252", errors="replace")
     text = text.replace("\r\n", "\n").strip()
     text = text.replace("\r\n", "\n").strip()
     if not text:
     if not text:
         raise TextFileError("Ce fichier texte est vide.")
         raise TextFileError("Ce fichier texte est vide.")

+ 2 - 0
changelog.txt

@@ -24,6 +24,8 @@ Corrections
   de prévenir l'administrateur pour un réglage du .env refusé, un crédit
   de prévenir l'administrateur pour un réglage du .env refusé, un crédit
   épuisé, un modèle introuvable ou un accès refusé ; les logs en donnent
   épuisé, un modèle introuvable ou un accès refusé ; les logs en donnent
   la cause.
   la cause.
+- Les fichiers .txt enregistrés en « Unicode » par le Bloc-notes (UTF-16)
+  sont lus, au lieu d'être refusés comme « pas du texte lisible ».
 
 
 
 
 Version 5.6 — 30/10/2026
 Version 5.6 — 30/10/2026