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.
Inverzní fce? Kde se to používá, tohle neznám...
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.
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
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... :)