Regex numéro de port réseau
L'auteur de la question de référence sur Stack Overflow a posté une regex avec une parenthèse non fermée — une vraie erreur de syntaxe. La réponse la plus votée (61 votes) corrige ça, mais son propre historique de commentaires révèle deux bugs réels distincts, corrigés l'un après l'autre au fil des années : elle acceptait « 0000 » comme port valide (branche basse mal bornée), puis, une fois ce point corrigé, une faute de frappe résiduelle (« 655[0-3] » au lieu de « 655[0-2] ») laissait passer les ports 65536 à 65539 — un vrai bug qui a même causé un ticket GitHub ouvert sur un projet tiers. Voici la version aujourd'hui pleinement corrigée, comparée à ces 3 étapes réelles de son histoire.
/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/passe 20/20 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — regex de l'auteur de la question, telle que postée, parenthèse non fermée (erreur de syntaxe réelle) | (6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3} | ne compile pas | — |
| Stack Overflow — forme historique de la réponse à 61 votes avant correction, acceptait « 0000 » (bug signalé en commentaire par elfan) | ^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$ | 16 / 20 | sûr |
| Stack Overflow — forme intermédiaire de la même réponse, faute de frappe résiduelle laissant passer les ports 65536-65539 (signalée en commentaire, avec un vrai ticket GitHub à l'appui) | ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-3][0-9]|6553[0-5])$ | 18 / 20 | sûr |
Implémentation
const re = new RegExp("^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$", "");
re.test(input);Limites
- Exclut le port 0, réservé et non attribuable à une application — cohérent avec la plage 1-65535 explicitement visée par la réponse source, mais certaines API systèmes (ex. « bind » avec le port 0 pour demander un port libre au hasard) l'acceptent dans un sens différent, hors du champ de cette regex.
- Ne distingue pas les ports système (0-1023, réservés, nécessitant des privilèges élevés), les ports enregistrés (1024-49151) et les ports dynamiques/éphémères (49152-65535) : ces trois catégories partagent la même forme numérique, seule leur signification d'usage diffère.
- Ne vérifie pas qu'un port donné est réellement ouvert, écouté par un service, ou disponible sur la machine visée : la forme seule ne dit rien de l'état réel du réseau.
- N'accepte aucun zéro de tête (« 007 », « 0080 ») même si certains outils système ou fichiers de configuration l'admettent par tolérance : les rejeter reste plus sûr pour distinguer une saisie décimale d'une notation octale ambiguë.