Vylepsenie validacie Form::EMAIL
- westrem
- Člen | 398
Zdravim,
tak na Nette som presiel tak pred 2 mesiacmi a mmtalne si stale dorabam urcite
featuresy, ktore som v mojom predslom FM mal nakodene ale v Nette mi chybaju.
Medzi ne patria aj oddelene Validatory, o ktore tu uz bolo viac komunitnych
pokusov (najvyraznejsie asi od vrtak-cz ).
Na jeho rieseni sa mi vsak nepacilo, ze v podstate robil presun validacnych metod z TextBase niekam inam. Moje riesenie je proste samostatna staticka trieda so vsetkymi stavajuci Nette validatormi (miestami vylepsenymi), ktore sa daju plne pouzit v Nette\Forms alebo hocikde v modeli prip. v aplikacii.
Podme ale od rozsiahlejsieho uvodu priamo k veci. Pocas tohto prepisovania a vytvarania validatorov, som sa jednak inspiroval svojimi uz napisanymi funkciami a druhorak Davidovou validaciou v TextBase pripadne FormControl. Po napisani validatorov prislo na testy. Tu som narazil na dve chyby (chybky).
- popisujem v tomto threade
- ktora sa tyka validacie e-mailovych adries sa pokusim popisat tu
Pre validaciu e-mailovych adries som sa nechal inspirovat touto peknou strankou: Comparing E-mail Address Validating Regular Expressions
Je tam zoznam dostupnych regexpov na validaciu e-mailovych adries, pricom iba jeden z nich kompletne prejde testami (ten prvy uvedeny).
Schvalne som teda podrobil Nette validator tomuto testu. Vysledky su podla mna vcelku slusne, no nie 100% tak ako by mohli byt:
Toto by mali byt validne e-maily
- l3tt3rsAndNumb3rs@domain.com: true- has-dash@domain.com: true
- hasApostrophe.o'leary@domain.org: true
- uncommonTLD@domain.museum: true
- uncommonTLD@domain.travel: true
- uncommonTLD@domain.mobi: true
- countryCodeTLD@domain.uk: true
- countryCodeTLD@domain.rw: true
- lettersInDomain@911.com: true
- underscore_inLocal@domain.net: true
- IPInsteadOfDomain@127.0.0.1: **false**
- IPAndPort@127.0.0.1:25: **false**
- subdomain@sub.domain.com: true
- local@dash-inDomain.com: true
- dot.inLocal@foo.com: true
- a@singleLetterLocal.org: true
- singleLetterDomain@x.org: true
- &*=?^+{}'~@validCharsInLocal.net: true
- foor@bar.newTLD: true
False znamena chybu, pretoze e-mail mal prejst
Toto by mali byt nevalidne e-maily
- missingDomain@.com: false- @missingLocal.org: false
- missingatSign.net: false
- missingDot@com: false
- two@@signs.com: false
- colonButNoPort@127.0.0.1:: false
- : false
- someone-else@127.0.0.1.26: **true**
- .localStartsWithDot@domain.com: false
- localEndsWithDot.@domain.com: false
- two..consecutiveDots@domain.com: false
- domainStartsWithDash@-domain.com: false
- domainEndsWithDash@domain-.com: false
- numbersInTLD@domain.c0m: **true**
- missingTLD@domain.: false
- ! "#$%(),/;<>[]`|@invalidCharsInLocal.org: false
- invalidCharsInDomain@! "#$%(),/;<>_[]`|.org: false
- local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org: false
True znamena chybu, pretoze e-mail nemal prejst
Verim, ze ked David tvoril regexp pre validaciu e-mailov, tak si poriadne nastudoval dane dokumenty (o com svedcia aj komentare pri kode a odkazy na konkretne RFC) avsak ocividne to nepokryva kompletny set (cim jeho validaciu nechcem zhadzovat, 4 chyby su podla mna este statocny vykon).
Bola by vsak snaha toto napravit a pouzit ten regexp co je na stranke preferovany ako jediny co presiel testami?
- Patrik Votoček
- Člen | 2221
Občas si říkám že problematika validace e-mailové adresy by měla mít vlastní vědní obor (pokud nemá). Protože i to tebou navrhované řešení není dokonalé. A řešení z nette ho za jisté situace válcuje. Tou situací je IDN. Jakožto majitel IDN domény jsem to prostě musel otestovat. Test přikládám zde https://gist.github.com/565491
- Jakub Nerad
- Člen | 21
Validátor na email má spíš fungovat když se někdo omylem přepíše. Což teď funguje velmi dobře. Nějaká dokonalost u emailu je pomalu na vědeckou práci.
- westrem
- Člen | 398
Och ospravedlnujem sa Davidovi, nejak ma nenapadlo pozriet si (resp. s GitHubom si natolko este netykam aby som vobec vedel ako) kto to commitoval.
Avsak ako som vravel, nijak extremne mi nevadi sucasny stav, podla mna Nette so svojim validatorom odvadza dobru pracu, ja som ho len porovnal s niecim co som uz poznal.
Vrtak-cz napsal:
Pekny test, skusil som si a naozaj na IDN to pada, kdezto Nette pouziva superset IDN znakov. Vysledok je teda vlastne 50:50 (prijatie nevalidneho e-mailu je vzdy lepsie ako odmietnutie validneho).
Vedecka prace
Presne tak, miestami to zaraza aj mna, nechapem preco pre e-mail, co je tak strasne dlho zauzivana vec na internete neexistuje ujednoteny format a teda regexp.
Riesenie
Riesenie problemu je v podstate podla mna, jednoduche, staci sa pozriet, kde Jakub Vrana navrhol superset of IDN a ako ho pouziva a toto doplnit do toho „hrozneho regexpu“ nasledovne:
"/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9\x80-\xFF]{1}[a-z0-9\x80-\xFF\-]{0,62}[a-z0-9\x80-\xFF]{1})|[a-z0-9\x80-\xFF])\.)+[a-z\x80-\xFF]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i"Vrtak-cz: ak si vo svojom teste das tento regexp namiesto toho povodneho, prejdu aj IDN domeny a vsetko co ma byt zelene je zelene a zvysok je cerveny, co na to poviete?
- David Grudl
- Nette Core | 8228
Emailové adresy jako IPInsteadOfDomain@127.0.0.1
nejsou
podporované záměrně. Takové adresy skutečně nikdo nemá. Smyslem
formulářové validace je odhalit nesmyslné adresy, ačkoliv mohou
být podle nějakého RFC platné.
- jtousek
- Člen | 951
David Grudl napsal(a):
Emailové adresy jako
IPInsteadOfDomain@127.0.0.1
nejsou podporované záměrně. Takové adresy skutečně nikdo nemá. Smyslem formulářové validace je odhalit nesmyslné adresy, ačkoliv mohou být podle nějakého RFC platné.
Souhlasím, v tom případě má smysl opravovat maximálně tuto
adresu:
numbersInTLD@domain.c0m