Aller au contenu
Aback Tools Logo

Corriger InvalidCharError dans le Sanitizer de Noms de Fichiers Python

Ce qui déclenche InvalidCharError de Python dans les sanitizers de noms de fichiers : caractères illégaux par OS, le problème des deux-points dans les horodatages, recette de sanitizer manuel en Python, règles multiplateformes et outils de validation gratuits.

DH
Tutorials & How-Tos11 min de lecture2,550 mots

L'`InvalidCharError` des bibliothèques Python d'assainissement de noms de fichiers est une erreur précise - elle se déclenche lorsqu'une chaîne de nom de fichier contient un caractère interdit par le système d'exploitation cible. Mais la cause est presque toujours la même : un nom de fichier est arrivé d'une saisie utilisateur, d'un téléversement de fichier ou d'une API externe sans avoir été validé au préalable. Ce guide explique exactement quels caractères déclenchent l'erreur sur chaque OS, comment la corriger, et comment intégrer l'assainissement dans votre code pour qu'elle n'atteigne jamais la production.

11Caractères illégaux sur Windows< > : " / \ | ? * et plus
2Caractères illégaux sur LinuxUniquement l'octet nul et la barre oblique
255Octets max. du nomLimite sûre multiplateforme

Qu'est-ce que FilenameSanitizer ?

`FilenameSanitizer` désigne des bibliothèques Python - le plus souvent `python-filenamesanitizer` et des paquets similaires - qui valident et nettoient les chaînes de noms de fichiers avant leur utilisation dans des opérations du système de fichiers. Ces bibliothèques vérifient le nom de fichier proposé par rapport aux règles du système d'exploitation cible et renvoient soit une version assainie, soit lèvent une exception lorsqu'un caractère ne peut pas être remplacé sans risque.

Pourquoi l'assainissement des noms de fichiers est nécessaire

Les noms de fichiers provenant de sources externes - téléversements d'utilisateurs, réponses d'API, données scrapées, enregistrements de base de données - contiennent fréquemment des caractères parfaitement valides dans le contexte source mais illégaux sur le système de fichiers de destination. Un nom comme `report: Q1/2026.pdf` est une étiquette humaine raisonnable, mais il contient `:` et `/` - tous deux illégaux sur Windows. Sans assainissement, l'appel `open()` lève une `OSError` ou le fichier est silencieusement tronqué au caractère illégal.

Ce que signifie InvalidCharError

InvalidCharError est l'exception spécifique levée lorsqu'un nom de fichier contient un caractère que la bibliothèque ne peut ni remplacer ni retirer automatiquement - ou lorsque la bibliothèque est configurée pour lever plutôt que d'auto-corriger. Le message d'exception inclut le nom de fichier original et le caractère fautif, ce qui vous donne tout le nécessaire pour corriger. Si vous voyez cette erreur sans traceback clair, collez la pile complète dans l'Explicateur de Tracebacks Python pour une explication en langage clair de la cause racine.

Note

Toutes les erreurs de noms de fichiers en Python ne viennent pas d'une bibliothèque d'assainissement. Un `ValueError` ou `OSError` identique peut être levé directement par `open()`, `os.rename()`, `pathlib.Path()` ou `shutil` quand un nom non assaini atteint un appel du système de fichiers. La correction est la même quelle que soit l'appel à l'origine de l'erreur - le nom doit être nettoyé avant toute opération du système de fichiers.

Qu'est-ce qui déclenche InvalidCharError ?

L'erreur se déclenche lorsque la chaîne du nom de fichier contient un ou plusieurs caractères que l'ensemble de règles du sanitizer marque comme illégaux. Les déclencheurs les plus courants se répartissent en quatre catégories, chacune avec un chemin de correction différent.

  • Séparateurs de chemin Windows - `:` (deux-points), `\\` (barre oblique inverse), `/` (barre oblique) ; fréquents dans les horodatages et chemins URL utilisés comme noms de fichiers
  • Caractères réservés du shell - `|`, `<`, `>`, `?`, `*`, `"` - courants dans les noms générés à partir de requêtes de recherche, titres ou noms de documents
  • Octets nuls et caractères de contrôle - points de code Unicode U+0000 à U+001F ; parfois injectés par une saisie malveillante ou une corruption d'encodage
  • Noms de périphériques réservés de Windows - CON, PRN, AUX, NUL, COM1-COM9, LPT1-LPT9 - illégaux comme noms de fichiers quelle que soit l'extension sur Windows

Le problème de l'horodatage

La source la plus fréquente d'`InvalidCharError` dans les applications réelles est un nom de fichier construit à partir d'un horodatage. Un datetime ISO 8601 comme `2026-06-11T14:30:00` contient un deux-points - illégal sur Windows. Tout code générant des noms comme `backup_2026-06-11T14:30:00.zip` échouera sur Windows mais réussira silencieusement sur Linux, créant un bug multiplateforme subtil. Remplacez les deux-points des horodatages par des tirets ou des points : `2026-06-11T14-30-00`.

Le problème de la saisie utilisateur

Lorsque les utilisateurs nomment des fichiers dans une interface web ou téléversent des fichiers depuis leurs appareils, les noms arrivent sans aucune garantie de validité. Un PDF nommé `Invoice: Client/Project Q4.pdf` est un nom tout à fait naturel rédigé par un humain qui contient trois caractères illégaux sur Windows. Traitez toujours tout nom de fichier qui ne provient pas de votre propre code comme une entrée non fiable nécessitant un assainissement avant usage.

Warning

Ne présumez jamais qu'un nom de fichier est sûr parce qu'il a survécu sur le système source. Linux autorise les noms avec `<`, `>`, `*` et `|` - des fichiers portant ces noms peuvent être téléversés depuis une machine Linux puis provoquer un `InvalidCharError` quand votre code ciblant Windows tente de les écrire. Assainissez toujours, quelle que soit l'origine du nom.

Caractères illégaux par système d'exploitation

Les trois grands systèmes d'exploitation ont des règles très différentes sur les caractères autorisés dans les noms de fichiers. Comprendre ces différences est essentiel pour écrire du code portable de manipulation de fichiers.

CaractèreWindowsmacOSLinux
/ (barre oblique)✗ Illégal✗ Illégal✗ Illégal (sép. de chemin)
\\ (barre oblique inverse)✗ Illégal✓ Autorisé✓ Autorisé
: (deux-points)✗ Illégal✗ Problème hérité✓ Autorisé
* ? " < > | (ensemble)✗ Illégal✓ Autorisé✓ Autorisé
Octet nul (\0)✗ Illégal✗ Illégal✗ Illégal
Caractères de contrôle (0-31)✗ Illégal✗ Illégal✗ Illégal
Point initial (.)✓ AutoriséFichier cachéFichier caché
Point ou espace final✗ Illégal✓ Autorisé✓ Autorisé
Noms réservés (CON etc.)✗ Illégal✓ Autorisé✓ Autorisé

Pour du code multiplateforme devant fonctionner sur les trois systèmes, la règle sûre est de considérer les règles Windows comme le minimum - tout caractère illégal sur Windows doit être assaini quel que soit l'OS réel d'exécution. Vous obtenez ainsi des noms de fichiers portables fonctionnant partout. Le Sanitizer de Noms de Fichiers pour Téléversements Multiplateformes valide simultanément contre les trois jeux de règles d'OS afin que vous puissiez vérifier n'importe quel nom en une seule passe.

Comment corriger l'erreur

Corriger un `InvalidCharError` implique toujours le même flux : trouver la source du nom de fichier, appliquer l'assainissement avant l'appel au système de fichiers, puis vérifier le résultat. Suivez ces étapes dans l'ordre.

1

Lisez le traceback complet pour identifier le caractère fautif

Le message d'`InvalidCharError` inclut à la fois la chaîne du nom de fichier original et le caractère précis rejeté. Copiez le traceback complet et notez le caractère. S'il s'agit d'un caractère de contrôle ou d'un octet nul, il peut être invisible dans la sortie d'erreur - utilisez `repr()` sur la chaîne du nom dans votre code pour voir la représentation échappée et identifier les caractères cachés.

2

Localisez où le nom de fichier prend source dans votre code

Remontez le nom de fichier jusqu'à sa source grâce à la pile d'appels du traceback. Sources courantes : le champ `filename` d'un téléversement multipart, une chaîne construite à partir de métadonnées utilisateur, un champ de réponse d'API, une colonne de base de données ou un listage de fichiers externe. Le lieu de correction est toujours à la source - pas au point où l'erreur est levée.

3

Appliquez l'assainissement à la frontière d'entrée

Ajoutez une passe d'assainissement immédiatement après l'entrée du nom dans votre système - au gestionnaire de téléversement, au parseur de réponses d'API, ou partout où les données externes deviennent pour la première fois un nom de fichier. Utilisez `re.sub(r'[<>:"/\\|?*\x00-\x1F]', '-', name)` comme remplacement de base, puis retirez les points et espaces finaux, vérifiez par rapport aux noms réservés Windows et tronquez à 255 octets. Utilisez le Validateur de Syntaxe Python pour vérifier l'absence d'erreurs de syntaxe dans votre fonction d'assainissement avant le déploiement.

4

Validez le nom assaini avant l'appel au système de fichiers

Après assainissement, validez le résultat avec le Sanitizer de Noms de Fichiers pour Téléversements Multiplateformes pour confirmer qu'aucun caractère illégal ne subsiste, que le nom n'est pas un nom de périphérique réservé Windows et que la longueur reste dans la limite de 255 octets. Cela attrape des cas limites qu'une simple substitution regex manque - comme un nom entièrement composé d'espaces après retrait, qui devient vide après rognage.

Sanitizer de Noms de Fichiers pour Téléversements Multiplateformes

Collez n'importe quel nom de fichier et validez-le simultanément contre les règles Windows, macOS et Linux - identifie les caractères illégaux, les noms réservés, les problèmes de longueur et fournit la version propre et sûre.

Open tool

Assainir les noms de fichiers manuellement en Python

Si vous préférez ne pas dépendre d'une bibliothèque tierce, vous pouvez implémenter un sanitizer de noms de fichiers robuste en Python pur. L'approche couvre toutes les restrictions Windows et multiplateformes sans aucune dépendance externe.

La logique d'assainissement centrale

Un sanitizer Python complet de noms de fichiers nécessite cinq opérations appliquées en séquence : normaliser l'Unicode vers la forme composée (NFC) afin que les caractères comme les lettres accentuées soient stockés comme points de code uniques ; remplacer tous les caractères illégaux Windows et les caractères de contrôle ASCII par un substitut sûr ; retirer les points, espaces et tirets initiaux et finaux, problématiques sur Windows ; vérifier par rapport à la liste des noms de périphériques réservés Windows et ajouter un suffixe en cas de correspondance ; et enfin tronquer à 255 octets une fois encodé en UTF-8.

Gérer les noms de fichiers Unicode

Les applications modernes gèrent couramment des noms de fichiers contenant des caractères non ASCII - arabe, chinois, japonais, lettres latines accentuées. Tous sont légaux sur les systèmes de fichiers modernes (NTFS, APFS, ext4) mais peuvent poser problème lors de conversions d'encodage. Un nom valide en UTF-8 peut se corrompre si le système de fichiers ou l'OS est configuré pour un encodage ancien comme Latin-1 ou Windows-1252. Si vous rencontrez des noms aux caractères altérés, passez-les dans l'Outil de Réparation Unicode et d'Encodage pour identifier et corriger le problème d'encodage avant l'assainissement.


Quand lever vs. quand auto-corriger

Vous avez deux choix lorsqu'un caractère illégal est trouvé : lever une exception (le comportement par défaut de la bibliothèque `python-filenamesanitizer`) ou auto-remplacer par un caractère sûr. Pour les gestionnaires de téléversement, l'auto-remplacement est généralement le bon choix - nettoyer silencieusement `invoice: Q1.pdf` en `invoice- Q1.pdf` vaut mieux qu'un échec du téléversement. Pour le code interne qui génère ses propres noms, lever est préférable - un `InvalidCharError` dans votre propre code est un bug à corriger, pas un cas limite à gérer en silence.

Tip

Lors de l'auto-remplacement de caractères, préférez le tiret (`-`) au tiret bas comme caractère de substitution. Les tirets sont plus lisibles que les tirets bas dans les noms de fichiers multi-mots et sont universellement autorisés sur tous les systèmes d'exploitation. Évitez de remplacer par un espace - bien que les espaces soient légaux dans les noms de fichiers sur tous les OS modernes, ils posent problème dans les commandes shell et certains outils anciens.

Bonnes pratiques multiplateformes pour les noms de fichiers

La stratégie d'assainissement la plus fiable est un ensemble de règles cohérentes appliquées à chaque frontière d'entrée, plutôt qu'une série de correctifs ad hoc qui s'accumulent avec le temps. Ces pratiques empêchent `InvalidCharError` et ses cousins d'apparaître dès le départ.

Construisez les noms de fichiers à partir de composants sûrs

Dans la mesure du possible, générez les noms de fichiers à partir d'entrées contrôlées plutôt que de transmettre directement des chaînes fournies par l'utilisateur. Construisez les noms à partir d'identifiants assainis, d'UUID ou d'horodatages aux deux-points remplacés : un UUID comme `550e8400-e29b-41d4-a716-446655440000` est déjà sûr sur toutes les plateformes. Si un nom lisible par un humain est requis, assainissez-le d'abord puis ajoutez l'identifiant sûr en suffixe pour garantir l'unicité.

Validez à chaque frontière d'OS

  • Téléversements de fichiers - assainissez le nom téléversé avant sauvegarde, même si votre framework web fournit un champ de nom de fichier
  • Réponses d'API - traitez tout champ de nom de fichier d'une API externe comme non fiable ; validez avant usage
  • Enregistrements de base de données - les noms stockés en base peuvent avoir été enregistrés avant la mise en place de vos règles d'assainissement
  • Fichiers de configuration - les noms lus depuis des fichiers de config peuvent être incorrects si la config a été éditée par un utilisateur
  • Arguments de ligne de commande - les arguments de chemin fournis par l'utilisateur peuvent contenir des expansions de shell ou des caractères spéciaux

Testez sur toutes les plateformes cibles

Un bug de nom de fichier qui ne se manifeste que sur Windows est invisible dans un environnement de développement exclusivement Linux. Si votre application tournera sur Windows, testez votre code de gestion de fichiers sur Windows - ou ajoutez un job CI exécuté sur un runner Windows. Le Sanitizer de Noms de Fichiers pour Téléversements Multiplateformes fournit une vérification agnostique de l'OS exécutable depuis n'importe quelle plateforme, en faisant un substitut pratique aux tests multi-OS pendant le développement.

Warning

N'utilisez pas `os.path.basename()` seul comme mesure de sécurité pour les noms de fichiers téléversés. Il retire les composants de chemin mais n'assainit pas les caractères illégaux. Un nom comme `../../../etc/passwd` devient `passwd` après `os.path.basename()` - une tentative de traversée de chemin - mais `invoice:Q1.pdf` reste `invoice:Q1.pdf` inchangé. Appliquez toujours la prévention de traversée de chemin et l'assainissement de caractères comme étapes séparées.

Valider les noms de fichiers avant usage

Un sanitizer qui auto-remplace les caractères est une sauvegarde de production. Un validateur qui vérifie et signale les problèmes est un outil de développement et de débogage. Tous deux ont leur rôle, et les utiliser ensemble vous donne la couverture la plus forte.

Ce que vérifie l'outil Filename Sanitizer

Le Sanitizer de Noms de Fichiers pour Téléversements Multiplateformes valide les noms de fichiers contre les trois grands jeux de règles d'OS en une passe. Il vérifie les caractères illégaux (Windows, macOS, Linux), les noms de périphériques réservés Windows, les points et espaces finaux (illégaux sur Windows), les points initiaux (signal de fichier caché sur Unix), les octets nuls et caractères de contrôle, et la longueur du nom en caractères comme en octets UTF-8. Il vous montre aussi la version sûre assainie du nom aux côtés du rapport de validation.

Intégrer la validation dans la CI

Pour les applications générant des noms de fichiers à partir de gabarits ou de motifs configurables, ajoutez un test unitaire qui valide les noms générés contre les règles multiplateformes à chaque build. Un gabarit de nom qui fonctionne dans votre environnement actuel peut produire un `InvalidCharError` après un changement de configuration introduisant un deux-points dans le motif. Le détecter en CI est nettement moins coûteux que le déboguer en production.

Key takeaways

  • `InvalidCharError` se déclenche lorsqu'un nom de fichier contient un caractère illégal sur l'OS cible - le message d'erreur identifie toujours le caractère précis.
  • Windows interdit `< > : " / \ | ? *`, les caractères de contrôle, les points/espaces finaux et les noms réservés (CON, NUL, COM1-9, LPT1-9).
  • Linux n'interdit que les octets nuls et les barres obliques - mais le code portable doit appliquer les règles Windows universellement.
  • Assainissez toujours les noms de fichiers à la frontière d'entrée (gestionnaire de téléversement, parseur d'API) plutôt que de capturer les exceptions après coup.
  • Utilisez le Sanitizer de Noms de Fichiers pour Téléversements Multiplateformes pour valider n'importe quel nom contre les trois jeux de règles d'OS en une passe.
  • Les noms de fichiers Unicode avec encodage corrompu nécessitent l'Outil de Réparation Unicode et d'Encodage avant l'assainissement.
  • Auto-remplacez les caractères illégaux par des tirets dans les gestionnaires de téléversement ; levez des exceptions dans le code interne où les noms invalides sont un bug à corriger.

Questions fréquentes

InvalidCharError is an exception raised by the `python-filenamesanitizer` library (and similar filename validation libraries) when a filename string contains one or more characters that are illegal on the target operating system. The error identifies the specific character that caused the rejection. It is most commonly encountered when handling filenames from user uploads, API responses, or external data sources that have not been validated before being passed to filesystem operations.

Windows forbids the following characters in filenames: `< > : " / \ | ? *` and all control characters (Unicode codepoints U+0000 through U+001F). Windows also reserves specific names for system devices: CON, PRN, AUX, NUL, COM1-COM9, and LPT1-LPT9 - these names cannot be used as filenames regardless of extension. Additionally, filenames cannot end with a dot (.) or a space. These rules apply to all Windows filesystems including NTFS and FAT32.

macOS and Linux (POSIX) filesystems are significantly more permissive. The only universally forbidden characters are the null byte (\0) and the forward slash (/). However, filenames beginning with a dot (.) are treated as hidden files, filenames beginning with a hyphen can interfere with command-line argument parsing, and spaces and special shell characters (`, $, !, &, ;, |, and others) create problems in shell scripts even if the OS allows them. For portable code, treat all Windows-illegal characters as off-limits.

You can sanitize filenames with a regular expression and a few string operations. Replace all Windows-illegal characters (`< > : " / \ | ? *`) and control characters with a hyphen or underscore. Strip leading and trailing dots and spaces. Check the result against the Windows reserved name list (CON, PRN, AUX, NUL, COM1-9, LPT1-9) and append a suffix if it matches. Truncate to 255 bytes for NTFS compatibility. This covers the vast majority of cases without requiring a third-party library.

In Django, the recommended approach is to override the `generate_filename()` method on your storage backend or use Django's built-in `get_valid_name()` utility from `django.utils.text`. This function strips characters that are not alphanumeric, dots, underscores, or hyphens. For uploads that may contain Unicode names or non-ASCII characters from international users, run the name through `unicodedata.normalize("NFC", name)` first to normalize composed forms, then apply the sanitizer.

Yes - if the exception is unhandled, the file write operation failed and no file was created on disk. The exception is raised before any data is written. You need to catch the exception, sanitize the filename, and retry the write with the clean name. In a web application, this means wrapping the filename sanitization in a try/except block in your upload handler, applying a fallback sanitizer when the error is caught, and logging the original filename for debugging.

The safest approach is proactive validation before attempting any filesystem operation. Pass the filename through the Filename Sanitizer for Cross-Platform Uploads tool to identify issues during development, and implement a programmatic check in your code using a validation function that tests against all three OS rule sets simultaneously. This is more reliable than catching exceptions after the fact, because some invalid filenames cause silent errors or incorrect behaviour rather than explicit exceptions.

The limit depends on the filesystem. NTFS (Windows) allows 255 UTF-16 code units for the filename component, excluding the path. Most Linux filesystems (ext4, XFS) allow 255 bytes in the filename component. macOS (APFS, HFS+) allows 255 UTF-16 code units. The safe cross-platform limit is 255 bytes. When filenames contain non-ASCII Unicode characters (which encode to 2-4 bytes each in UTF-8), a filename that appears short in characters can exceed 255 bytes - always measure in encoded bytes when enforcing the limit.

ShareXLinkedIn