Přes Form::EMAIL neprojde email uzivatel.@server.cz

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
lubos
Člen | 22
+
0
-

Dobrý den,
narazil jsem teď v jedné aplikaci na stížnost návštěvníka serveru, neprochází mu přes formulář jeho email ve tvaru uzivatel.@server.cz, (tečka před zavináčem). Podle RFC je to validní.
Předpokládám že reg výraz pro kontrolu emailů je v souboru InstantClientScript.php toto:

<?php
'res = /^[^@\s]+@[^@\s]+\.[a-z]{2,10}$/i.test(val);';
?>
lubos
Člen | 22
+
0
-

Aha tak toto je jen javascriptový reg výraz, přes který tento email prochází.

vkuzel
Člen | 15
+
0
-

Reg. výraz pro kontrolu emailu na straně serveru je v souboru Forms/Controls/TextBase.php na řádku 157:

<?php
	/**
	 * Email validator: is control's value valid email address?
	 * @param  TextBase
	 * @return bool
	 */
	public static function validateEmail(TextBase $control)
	{
		$atom = "[-a-z0-9!#$%&'*+/=?^_`{|}~]"; // RFC 5322 unquoted characters in local-part
		$localPart = "(\"([ !\\x23-\\x5B\\x5D-\\x7E]*|\\\\[ -~])+\"|$atom+(\\.$atom+)*)"; // quoted or unquoted
		$chars = "a-z0-9\x80-\xFF"; // superset of IDN
		$domain = "[$chars]([-$chars]{0,61}[$chars])"; // RFC 1034 one domain component
		return (bool) preg_match("(^$localPart@($domain?\\.)+[a-z]{2,14}\\z)i", $control->getValue()); // strict top-level domain
	}
?>
JakubS
Člen | 15
+
0
-

lubos napsal(a):

… neprochází mu přes formulář jeho email ve tvaru uzivatel.@server.cz, (tečka před zavináčem). Podle RFC je to validní. …

IMHO se nejedná o validní adresu viz např. https://en.wikipedia.org/…mail_address#… (pokud se nepletu tak Seznam.cz jeden čas takové adresy umožňoval zřídit -jak se zdá doposud se neodhodlal k jejich deaktivaci.)

Ondřej Mirtes
Člen | 1536
+
0
-

Můžu potvrdit zkušenost se Seznamem – adresy s tečkami na konci tam jeden čas šly založit a fungovaly, od nějaké doby ale na ně nelze žádný e-mail doručit.

vkuzel
Člen | 15
+
0
-

Ahoj,

RFC 5322 říká, že adresa se skládá:

addr-spec       =   local-part "@" domain

přičemž local-part je:

local-part      =   dot-atom / quoted-string / obs-local-part

přičemž pokud zapisujeme dot-atom, což zapisujeme, pak tedy je:

dot-atom        =   [CFWS] dot-atom-text [CFWS]

přičemž dot-atom-text je:

dot-atom-text   =   1*atext *("." 1*atext)

tzn. kolem tečky musí být atext, tečka nemůže být před atextem ani po něm, ale teoreticky by mohla být tečka zahrnuta v atextu, proto, když se podíváme dál, tak atext je:

atext           =   ALPHA / DIGIT /    ; Printable US-ASCII
                       "!" / "#" /        ;  characters not including
                       "$" / "%" /        ;  specials.  Used for atoms.
                       "&" / "'" /
                       "*" / "+" /
                       "-" / "/" /
                       "=" / "?" /
                       "^" / "_" /
                       "`" / "{" /
                       "|" / "}" /
                       "~"

ALPHA a DIGIT jsou alfanumerické znaky, tzn. písmenka a číla, plus máme tam ještě speciální znaky se speciální poznámkou:

specials        =   "(" / ")" /        ; Special characters that do
                       "<" / ">" /        ;  not appear in atext
                       "[" / "]" /
                       ":" / ";" /
                       "@" / "\" /
                       "," / "." /
                       DQUOTE

mezi kterými je i tečka, tzn. uživatel skutečně nemůže začínat nebo končit tečkou.


Pokud bychom zapisovali obst-local-part, tak dojdeme k:

obs-local-part  =   word *("." word)
word            =   atom / quoted-string
atom            =   [CFWS] 1*atext [CFWS]

Záměrně jsem vynechal zápis uživ. jména (local-part) pomocí quoted-string, protože ten by problém s tečkou v adrese měl řešit. To znamená, že pokud uživ jméno obsahuje některé nepovolené znaky, je možné toto méno kódovat pomocí quoted-string a odeslat a příjemce by si s tím měl už umět poradit.

Přes javascriptovou kontrolu email s tečkou v local-part nakonci projde, protože se evidentně jedná pouze o zjednodušenou kontrolu, kdežto v php se již kontroluje důkladněji. Pro představu validace adresy podle staršího RFC 822 vypadá nějak takhle: http://www.ex-parrot.com/…Address.html

Validace emailové adresy není rozhodně jednoduchá úloha, protože a) RFC umožnuje vytvářet poměrně hodně zběsilostí (kombinací) a b) skoro nikdo se dle RFC neřídí, proto potom vznikají adresy s tečkou na konci a pod. Pokud ale chce formulář v Nette validovat tak, aby bylo zaručeno že na zvalidovanou adresu dorazí email v pořádku, pak by se měl co nejvíce přibližovat RFC a nepovolovat různé zběsilosti typu email s tečkou na konci, protože na jeden server email s takovou adresou dorazí a na dalších 10 ne. Povolovat takové zběsilosti znamená za chvíli odstranit kontrolu úplně.


Řešení:

  1. Zadat adresu v quoted-string formátu ;)
  2. Pokud budeš chtít, aby tvůj formulář tuto adresu validoval jako korektní, napiš si vlastní regulární výraz a přidej formuláři pravidlo:
<?php
$form->addRule(Form::REGEXP, 'Email není správný.', "/regularni vyraz/");
?>

Editoval vkuzel (24. 3. 2010 10:51)

Jan Jakeš
Člen | 177
+
0
-

Schmutzka: Fuj, tohle bych vhodný rozhodně nenazýval. Oproti tomu v Nette nebo RFC je spíš směšný :D

PS: Zdravim bývalého spolužáka ;)