Konec v regulárním výrazu
Školení, která pořádám
Pokud v regulárním výrazu chcete strefit konec řetězce, použijete výraz $
. Osobně jsem až donedávna nevěděl, že preg_match('~a$~', "a\n")
platí také. V HTTP nebo SMTP hlavičkách má znak konce řádku speciální význam, takže pokud na tomto místě kontrolujete data (např. e-mailovou adresu nebo adresu pro HTTP přesměrování) funkcí preg_match, může dojít k problémům. Netvrdím, že přímo bezpečnostním, protože za znak konce řádku už nemůžete nic přidat, ale přesun části hlaviček do těla zprávy nemusí být také dvakrát příjemný. Tedy teoreticky by mohlo dojít i k bezpečnostním problémům – odsunutím hlavičky Content-Type
by se klientovi nepředala informace o kódování a pokud by klient v tom případě použil jiné kódování, byl by kód náchylný ke XSS i pokud by všechna data byla ošetřena funkcí htmlspecialchars, ovšem s jiným kódováním.
Uvedené chování je možno potlačit modifikátorem D
nebo použitím \z
místo $
. Připomínám, že modifikátor m
způsobí, že $
strefí kromě konce řetězce také každý konec řádku.
Diskuse
Ja cetl "Konec regularnich vyrazu". Az na konci jsm si uvedomil spravny nazev. HUH
V Perlových regulárech (nevím, jak v POSIX) existuje vychytávka, u které modifikátor D není třeba využít.
Pro skutečný konec řetězce lze využít metaznak \z (inverzní funkci má \Z), pro jeho skutečný začátek (neboť ^ taky není úplně bezpečné) zase \a (inverzní fce \A).
Pak můžeš testovat zečátek/konec řetězce bez ohledu na znak nového řádku nebo na modifikátor m.
Díky za tip, doplnil jsem to do článku. Co myslíš tím, že "^ taky není úplně bezpečné"? Jenom chování s modifikátorem m?
Ano, s modifikátorem m strefí ^ i začátek nového řádku, \a nikoliv.
Dero:
To je jednoduché, tento metaznak bude vyhodnocen kladně jen pokud nenastal konec/začátek celého řetězce.
Takže RegExpu /test\Z/ vyhoví třeba řetězec "test lidské hlouposti", ale už ne "to je mi tedy test".
Marek:
Uvedený příklad nefunguje (testu vyhovuji oba, se "z" i "Z"). V manuálu se píše:
\Z - end of subject or newline at end (independent of multiline mode)
\z - end of subject (independent of multiline mode)
Tedy až pokud by za řetězcem "to je mi tedy test" nasledoval novy radek, "z" neprojde, ale "Z" ano.
Jakub Vrána :
Dero to trochu popletl. Ve skutečnosti to je takhle:
\a znak 0x07
\A začátek řetězce
\z konec řetězce
\Z konec řetězce nebo \n před koncem
Dero:
Ano, omlouvám se, nějak se mi to v hlavě pomíchalo. Specifikace mluví jasně, totiž přesně tak, jak píše Jakub.
Ondrej Ivanic:
Este dalsie info k teme:
http://www.php-security.org/MOPB/PMOPB-45-2007.htmlJa este pouzivam pred validaciou trim() a az nasledne preg_match() s modifikatorom D. S \z a \a som este nepouzil, mozno sa mi zapacia. trim() som sa naucil pouzivat az potom ked som cistil jednu rozsiahlu databazu od zbytocnych whitespaces... :)
Diskuse je zrušena z důvodu spamu.