Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Quelle syntaxe pour une adresse de courriel ?

26 réponses
Avatar
Olivier Miakinen
[ publication dans fr.comp.lang.php et fr.comp.mail,
suivi dans fr.comp.mail seul ]

Bonjour,

Lassé de voir tant de fonctions de contrôle des adresses de courriel
incorrectes, qui refusent par exemple les adresses « plussées » comme
la mienne (om+news en partie gauche) mais aussi les TLD¹ de plus de
trois caractères tels que .name, .aero ou .museum, j'ai l'intention de
faire inclure dans la FAQ de fr.comp.lang.php une fonction correspondant
mieux à la réalité.

Du coup, j'ai lu les RFC 952 et 1035 (noms de domaine), 2822 (format de
messages), 3696, et d'autres.

Il en ressort les choses suivantes.

1) Pour la partie gauche, avant l'arrobe (@)
--------------------------------------------
1a) Cette partie est composée d'une ou plusieurs sous-parties séparées
par des points (.).
1b) Chaque sous-partie est constituée d'au moins un caractère (donc on
n'a pas de point au début, ni à la fin, et on ne peut pas non plus
avoir deux points de suite.
1c) Les caractères suivants peuvent être utilisés tels quels, sans
protection :
- les lettres majuscules et minuscules sans accent (A à Z et a à z)
- les chiffres (0 à 9)
- les caractères !#$%&'*+-/=?^_`{|}
1d) Cela étant, on peut toujours utiliser d'autres caractères, y
compris l'espace ( ) et l'arrobe (@) à condition de les protéger,
par exemple <"John@Doe"@example.com> ou <John\ Doe@example.com>.

2) Pour la partie droite, après l'arrobe (@)
--------------------------------------------
2a) Cette partie est aussi composée d'une ou plusieurs sous-parties
séparées par des points (.).
2b) Là encore chaque sous-partie est constituée d'au moins un caractère.
2c) D'après le RFC 952, la syntaxe de chaque sous-partie est très
stricte :
- d'abord une lettre (A à Z ou a à z)
- suivie éventuellement par un certain nombre de lettres, de
chiffres (0 à 9) et de traits d'union (-)
- mais ne pouvant finir que par une lettre ou un chiffre (donc
pas un trait d'union
2d) D'après le RFC 1035, la syntaxe décrite ci-dessus n'est qu'une
« preferred syntax », tandis qu'en réalité à peu près n'importe
quelle chaîne de bits pourrait être stockée dans un DNS.
2e) L'expérience montre que les noms de sous-domaine ne commencent
pas forcément par une lettre, et d'ailleurs ne contiennent même pas
obligatoirement de lettre (ex : 123.net ou 93.fr).
2f) En revanche, il semble établi que le trait d'union ne peut jamais
être le premier ni le dernier caractère d'un nom de sous-domaine.
2g) Le RFC 1035 limite chaque nom de sous-domaine à 63 octets au
maximum, et le FQDN² à 255 octets au maximum.
2h) Le RFC 3696 considère qu'en dehors des applications chargées de
gérer les TLD eux-mêmes, tout nom de domaine devrait être un FQDN
avec donc au moins un point (.) séparant deux sous-domaines.

3) Pour l'ensemble
------------------
Le RFC 3696 limite la partie gauche à 64 octets au maximum, soit un
total de 320 octets au maximum pour l'adresse complète (64+1+255).


Tout ceci étant posé, j'envisage de conserver les règles suivantes :
(1a), (1b) et (1c) ; (2a), (2b), (2f), (2g) et (2h) ; (3). J'éliminerais
la possibilité (1d). Quant à (2c), (2d) et (2e), j'utiliserais une règle
(2c) assouplie pour accepter un chiffre comme premier caractère de
chaque sous-domaine (ce qui légitime les adresses constatées en (2e)).


En PHP, je construirais donc les expressions rationnelles suivantes :
// partie gauche
$atext = '[A-Za-z0-9!#$%&\'*+/=?^_`{|}-]';
$atom = "$atext+"
$leftpart = "$atom(\.$atom)*";
// partie droite
$letdig = '[A-Za-z0-9]';
$letdighyp = '[A-Za-z0-9-]';
$subdomain = "$letdig($letdighyp{0,61}$letdig)?";
$domain = "$subdomain(\.$subdomain)+";
// expression globale
$regexp = "$leftpart@$domain";

Il ne resterait plus qu'à tester indépendamment les longueurs max
respectives des parties gauche et droite (64 à gauche, 255 à droite).


En espérant ne pas vous avoir assommés avec ce long article, j'espère
avoir vos réactions.

Cordialement,
--
Olivier Miakinen
¹ TLD = Top level domain = domaine de premier niveau
² FQDN = Fully-qualified domaine name = nom de domaine complet

10 réponses

1 2 3
Avatar
Olivier Miakinen
Le 03/03/2006 11:27, F. Senault me répondait :

[...] Pourrais-tu juste préciser dans quelles circonstances il t'a
été proposé ces caractères exotiques dans des adresses qui se sont
ensuite révélées fausses ?


Non, en fait, j'utilise ce genre d'expressions pour parser des pages web
(notamment mon projet de webnews qui est soigneusement rangé au fond
d'un carton). [...]


Merci des précisions.

Juste pour savoir aussi : la traduction d'adresses de type Lotus Notes
ou Lotus Domino (X500 ?) ne pourrait-elle pas contenir des « % » par
exemple ?


Probablement, j'ai peut être été un peu large sur ce coup-là.


Ce n'est peut-être pas le cas pour Lotus Chose, puisque à mon boulot
il y a une grande majorité d'utilisateurs de ce machin, mais que leur
adresse vue de l'extérieur est très classique (), et
qu'apparemment leur adresse interne permet cela. Je ne suis hélas pas
très au courant de ce qui existe réellement.

Le RFC semblait vouloir permettre que le plus grand nombre possible de
types d'adresses soit accepté, mais c'est peut-être bien inutile.

[...] On trouve encore de nombreuses expressions
qui refusent les TLD dont la longueur n'est pas 2 ou 3, et celles-là
risquent d'être encore longtemps sur les sites web et dans les archives.
De la même manière, si je restreins les TLD possibles à {2,6} caractères
il est très possible qu'un .Z ou un .DOMAINS soit créé dès le lendemain.


Et soit utilisé légitimement quelque part entre six mois et quatre ans
après sa création. De quand date la création de .name / .info ? Quand
as-tu reçu pour la première fois un mail légitime venant de ces TLDs ?
Tu as déjà reçu quelque chose de valable en .museum ? Ca laisse
amplement le temps de mettre à jour une expression régulière !


Tu as parfaitement raison sur ce point, mais d'un autre côté le premier
résultat quand on cherche « table ascii » sur le web est une page qui
explique sans rire qu'il y a des caractères ASCII (dits « extended »)
à partir de la position 128. Ces caractères ne sont d'ailleurs pas ceux
de ISO-8859-1, ni ceux de CP1252, même pas ceux de CP850, mais ceux de
CP437 ! Ça fait combien de temps que MS-DOS est passé par défaut de
CP437 à CP850 ? Et ça fait combien de temps que Windows est devenu
plus célèbre que MS-DOS ? Enfin comment ça se fait qu'en 2006 on trouve
une page web qui décrit CP437 sans connaître son nom et sans citer les
autres (y compris Unicode), et que ce soit le premier résultat trouvé
par Google ?

J'ai fait une digression, mais c'était pour illustrer le fait qu'une
erreur ou une maladresse, une fois écrite, risque de vivre *beaucoup*
plus longtemps qu'on ne le voudrait.

Tiens, en regardant mieux, je vois que tu interdis déjà les deux points
à la suite dans la partie droite de l'adresse. C'est vrai que dans la
partie gauche c'est peut-être moins embêtant...


Je ne sais pas du tout s'il est valide d'avoir .. dans la partie
gauche ; de nouveau, d'expérience, c'est un cas que je n'ai jamais vu se
présenter.


Si je comprends bien le RFC 2822 (et dieu sait qu'il est difficile à
lire), les seuls cas où l'on pourrait avoir deux points de suite sont :
- entre guillemets :
<"machin..truc"@example.com>
- avec un caractère d'échappement (syntaxe RFC 822 obsolète dans 2822) :


Dans ce dernier cas, je me demande d'ailleurs si les syntaxes suivantes
sont ou non équivalentes :



En d'autres termes, est-ce que le . seul est un séparateur d'atomes
alors que le . serait un caractère comme un autre ? Inutile de me
répondre, en réalité je ne me soucie guère de ces cas limites (et
obsolètes).

[...] je reste convaincu que le test sur la composition du TLD est a
garder. Au moins, rajoute une clause pour interdire le ".invalid"...
(Sept lettres !) :)


J'avais pensé au « .invalid » et j'en toucherai probablement un mot dans
la FAQ. Il y a aussi les « .test », « .example » et « .localhost » (RFC
2606). Cela dit, l'expression régulière n'est là que pour éviter dès le
départ les cas les plus tordus, et la validation de l'adresse ne peut
se faire qu'après envoi d'une demande de confirmation à cette adresse.
Tester le .invalid me semble inutile dans cette optique.


Cordialement,
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)


Avatar
Olivier Miakinen

La question que je posais au groupe, c'était dans quelle mesure on doit
sacrifier la complétude à la simplicité. Par exemple, dois-je accepter
une adresse du style "John.Doe"@miakinen.net ou "John Doe"@miakinen.net,
ou bien dois-je me limiter seulement à ?


Je commence à penser qu'une expression plus stricte (qui accepte moins
de cas légaux mais accepte ce que "les internautes moyens" considèrent
comme valide) peut être une solution acceptable, à condition de ne pas
rejetter les autres, mais plutôt de les faire passer par la fonction
plus complète et de demander une validation manuelle.

Donc :

=> acceptée immédiatement
John => rejetée immédiatement, puis par l'expression
plus complète.

"John.Doe"@miakinen.net => repéchée par l'expression plus complète, mais
en attente de validation.


Attention ici ! Toute adresse, même syntaxiquement plausible, doit
encore être validée en y envoyant une demande de confirmation
d'inscription par courriel, ne serait-ce que pour éviter de faire
spammer son voisin en l'inscrivant à une liste de diffusion sans lui
demander son avis !

Je crois fondamentalement, même si ce n'était pas clair dans mon premier
article, que le but principal d'une fonction de contrôle est surtout de
protéger le site web qui reçoit l'adresse, et de l'empêcher de se faire
pirater ou transformer en relais ouvert. Voir par exemple ici comment un
site a servi de passerelle à spam en acceptant une adresse qui contenait
des sauts de ligne : <news:43f3c086$0$21295$.

Mais si cela peut être important et pratique pour une newsletter, ça
risque de compliquer inutilement un simple formulaire de contact...


Là encore je ne crois pas qu'il faille faire de différence : on vérifie
que l'adresse ressemble à quelque chose de propre et que ça ne va pas
tout casser, puis on envoie le message (un seul) à cette adresse.

[...]

Ce n'est qu'une idée pour l'instant, je n'ai pas une énorme expérience
dans le domaine, donc toutes les réactions sont les bienvenues.


Idem.

Cordialement,
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)


Avatar
Patrick Mevzek
Là je suis un peu réticent. On trouve encore de nombreuses expressions
qui refusent les TLD dont la longueur n'est pas 2 ou 3, et celles-là
risquent d'être encore longtemps sur les sites web et dans les archives.
De la même manière, si je restreins les TLD possibles à {2,6} caractères
il est très possible qu'un .Z ou un .DOMAINS soit créé dès le lendemain.


Et soit utilisé légitimement quelque part entre six mois et quatre ans
après sa création. De quand date la création de .name / .info ? Quand
as-tu reçu pour la première fois un mail légitime venant de ces TLDs ?
Tu as déjà reçu quelque chose de valable en .museum ? Ca laisse
amplement le temps de mettre à jour une expression régulière !


Manifestement non. L'usage des nouveaux gTLDs, à commencer par .INFO est
ralenti à cause de tous les filtrages incorrects qui sont faits.

Autant le standard dit maximum 63, ok, autant il ne dit rien sur la taille
d'un TLD. Je ne vois donc absolument pas pourquoi faire un tel filtrage.
Quite à faire un filtrage précis, il faudrait alors comparer avec la
liste complète des TLDs valides... mais liste qu'il faudra mettre à jour.

Compte tenu des copier coller divers, faire une expression de filtrage à
l'heure actuelle qui fait de nouveau une limite à 3 caractères pour le
TLD, c'est clairement anti-productif et une baffe à l'avenir.

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>


Avatar
Olivier Miakinen
Le 03/03/2006 20:03, j'écrivais :

- entre guillemets :
<"machin..truc"@example.com>
- avec un caractère d'échappement (syntaxe RFC 822 obsolète dans 2822) :



Tiens, c'est drôle, mon Mozilla reconnaît bien une adresse de courriel
dans la syntaxe obsolète, mais pas dans l'autre... ;-)

Avatar
Olivier Miakinen

[...]

Il en ressort les choses suivantes.

1) Pour la partie gauche, avant l'arrobe (@)
--------------------------------------------
1a) Cette partie est composée d'une ou plusieurs sous-parties séparées
par des points (.).
1b) Chaque sous-partie est constituée d'au moins un caractère (donc on
n'a pas de point au début, ni à la fin, et on ne peut pas non plus
avoir deux points de suite.
1c) Les caractères suivants peuvent être utilisés tels quels, sans
protection :
- les lettres majuscules et minuscules sans accent (A à Z et a à z)
- les chiffres (0 à 9)
- les caractères !#$%&'*+-/=?^_`{|}


Je viens de faire l'expérience de m'envoyer des courriers avec un peu
n'importe quoi dans la partie gauche, en utilisant Mozilla. Le résultat
de ce test, c'est que je peux mettre n'importe lesquels des caractères
indiqués, sauf deux : le point d'exclamation (!) et le pourcent (%). Je
peux même mettre deux points de suite.

Voici une adresse qui fonctionne :
#$&'*-/=?^_`{|}..+

Mais la face cachée de tout cela, c'est que Mozilla rajoute de lui-même
les guillemets quand il estime qu'ils sont nécessaires, ce qui arrive
même pour l'histoire des points doublés. Ainsi, reste
, mais devient "o..m"@miakinen.net !

1d) Cela étant, on peut toujours utiliser d'autres caractères, y
compris l'espace ( ) et l'arrobe (@) à condition de les protéger,
par exemple <""@example.com> ou <John .


Alors que Mozilla met de lui-même des guillemets je ne peux pas décider
moi-même de les y mettres, et mes essais avec espace ou @ se sont
révélés... aléatoires.

Avatar
F. Senault

Là je suis un peu réticent. On trouve encore de nombreuses expressions
qui refusent les TLD dont la longueur n'est pas 2 ou 3, et celles-là
risquent d'être encore longtemps sur les sites web et dans les archives.
De la même manière, si je restreins les TLD possibles à {2,6} caractères
il est très possible qu'un .Z ou un .DOMAINS soit créé dès le lendemain.


Et soit utilisé légitimement quelque part entre six mois et quatre ans
après sa création. De quand date la création de .name / .info ? Quand
as-tu reçu pour la première fois un mail légitime venant de ces TLDs ?
Tu as déjà reçu quelque chose de valable en .museum ? Ca laisse
amplement le temps de mettre à jour une expression régulière !


Manifestement non. L'usage des nouveaux gTLDs, à commencer par .INFO est
ralenti à cause de tous les filtrages incorrects qui sont faits.


Erm, c'est de la grosse extrapolation, ça, IMHO.

Autant le standard dit maximum 63, ok, autant il ne dit rien sur la taille
d'un TLD. Je ne vois donc absolument pas pourquoi faire un tel filtrage.
Quite à faire un filtrage précis, il faudrait alors comparer avec la
liste complète des TLDs valides... mais liste qu'il faudra mettre à jour.


On ne peut pas dire que ça change tous les jours.

Compte tenu des copier coller divers, faire une expression de filtrage à
l'heure actuelle qui fait de nouveau une limite à 3 caractères pour le
TLD, c'est clairement anti-productif et une baffe à l'avenir.


Au passage, l'expression dont il était question ne limitait pas à 3
caractères. JDC, JDR.

Fred
--
Feel the bile rising From your guilty past
With your nerves in tatters As the cockleshell shatters
And the hammers batter Down your door
/You better run !/ (Pink Floyd, Run Like Hell)



Avatar
F. Senault

Le 03/03/2006 11:27, F. Senault me répondait :


/.../

Tiens, en regardant mieux, je vois que tu interdis déjà les deux points
à la suite dans la partie droite de l'adresse. C'est vrai que dans la
partie gauche c'est peut-être moins embêtant...


Je ne sais pas du tout s'il est valide d'avoir .. dans la partie
gauche ; de nouveau, d'expérience, c'est un cas que je n'ai jamais vu se
présenter.


Si je comprends bien le RFC 2822 (et dieu sait qu'il est difficile à
lire), les seuls cas où l'on pourrait avoir deux points de suite sont :
- entre guillemets :
<"machin..truc"@example.com>
- avec un caractère d'échappement (syntaxe RFC 822 obsolète dans 2822) :


Dans ce dernier cas, je me demande d'ailleurs si les syntaxes suivantes
sont ou non équivalentes :



En d'autres termes, est-ce que le . seul est un séparateur d'atomes
alors que le . serait un caractère comme un autre ? Inutile de me
répondre, en réalité je ne me soucie guère de ces cas limites (et
obsolètes).


Note que, dans la configuration des serveurs de courrier que je connais,
autant dans la partie droite la notion d'atomes est cruciale - DNS
oblige - autant dans la partie gauche, elle n'a strictement aucun
impact.

[...] je reste convaincu que le test sur la composition du TLD est a
garder. Au moins, rajoute une clause pour interdire le ".invalid"...
(Sept lettres !) :)


J'avais pensé au « .invalid » et j'en toucherai probablement un mot dans
la FAQ. Il y a aussi les « .test », « .example » et « .localhost » (RFC
2606). Cela dit, l'expression régulière n'est là que pour éviter dès le
départ les cas les plus tordus, et la validation de l'adresse ne peut
se faire qu'après envoi d'une demande de confirmation à cette adresse.
Tester le .invalid me semble inutile dans cette optique.


Mon point de vue - généralement orienté serveurs de courrier, de news,
spam et anti-spams - est fatalement différent. Enfin, ça n'est guère
important !

Fred
--
Why was I one of the chosen ones?
Until the fight I could not see
The magic and the strength of my power
It was beyond my wildest dreams (Within Temptation, Dark Wings)



Avatar
Patrick Mevzek
Manifestement non. L'usage des nouveaux gTLDs, à commencer par .INFO est
ralenti à cause de tous les filtrages incorrects qui sont faits.


Erm, c'est de la grosse extrapolation, ça, IMHO.


Quand je vois le nombre de sites web qui refusent mon email (avec un + à
gauche), signe du nombre affolant de tests foireux, c'est tout sauf de
l'extrapolation selon moi.

Je ne vois donc absolument pas pourquoi faire un tel
filtrage. Quite à faire un filtrage précis, il faudrait alors
comparer avec la liste complète des TLDs valides... mais liste qu'il
faudra mettre à jour.


On ne peut pas dire que ça change tous les jours.


Ce qui ne justifie pas non plus un filtrage sur la taille.

Compte tenu des copier coller divers, faire une expression de filtrage
à l'heure actuelle qui fait de nouveau une limite à 3 caractères
pour le TLD, c'est clairement anti-productif et une baffe à l'avenir.


Au passage, l'expression dont il était question ne limitait pas à 3
caractères. JDC, JDR.


Ce n'est pas vous qui avait dit:
Par contre, pour compléter ton expression rationnelle, je te
conseillerais bien de te fendre d'un ([a-z]{2,6}) pour le (cc)TLD (de
mémoire, il me semble que ça suffit).

Ce qui, selon moi, est une erreur. Erreur faite dans le passé, et je
trouve donc dommage de la faire dans le futur. Surtout compte-tenu des
évolutions (IDNs en particulier)

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>
Dépêches sur le nommage <news://news.dotandco.net/dotandco.info.news>


Avatar
Olivier Miakinen

[...] Cela dit, l'expression régulière n'est là que pour éviter dès le
départ les cas les plus tordus, et la validation de l'adresse ne peut
se faire qu'après envoi d'une demande de confirmation à cette adresse.
Tester le .invalid me semble inutile dans cette optique.


Mon point de vue - généralement orienté serveurs de courrier, de news,
spam et anti-spams - est fatalement différent.


Bon, je veux bien. Mais que t'apporte de plus le fait de détecter
immédiatement comme invalide l'adresse
alors que ne sera pas détectée, pas plus que
?

Enfin, ça n'est guère important !


C'est bien mon sentiment.


Avatar
F. Senault


[...] Cela dit, l'expression régulière n'est là que pour éviter dès le
départ les cas les plus tordus, et la validation de l'adresse ne peut
se faire qu'après envoi d'une demande de confirmation à cette adresse.
Tester le .invalid me semble inutile dans cette optique.


Mon point de vue - généralement orienté serveurs de courrier, de news,
spam et anti-spams - est fatalement différent.


Bon, je veux bien. Mais que t'apporte de plus le fait de détecter
immédiatement comme invalide l'adresse
alors que ne sera pas détectée, pas plus que
?


Rapport qualité prix : j'élimine sans faute et pour un prix minable un
truc qui ne m'intéressera certainement pas, sans besoin de technologies
compliquées comme des lookups DNS ou ce genre de choses.

Fred
--
Je regarde le bleu profond se voiler
Parfois, un point lumineux se charge de me rappeler
Que je ne suis pas ici pour paresser
Et que quelque part on a besoin de moi pour aider (Merzhin, Par delà)



1 2 3