Statement on glibc/iconv Vulnerability

Önceleme karakteri

Tersbölü karakterinin çeşitli kullanımları vardır. Tersbölünün ilk kullanım çeşidinde, bir harfin veya bir rakamın soluna konmuşsa karakterin özel anlamını kaldırır; karakter sınıflarının içinde ve dışında bir önceleme karakteri olarak iş görür.

Örneğin, şablonunuzun "*" karakteri ile eşleşmesini isterseniz, şablonu "\*" biçiminde yazmalısınız. Tersbölü karakterinin öncelediği karakter bir düzenli ifade işleci olsun ya da olmasın yorumu değişmeyecek, daima öncelediği karakter kendisiyle eşleşecektir. Sonuç olarak, önceleme işleci harf veya rakam olmayan karakterlerle de güvenle kullanılabilmektedir. Özellikle, bir tersbölü karakteri ile eşleşme sağlamak için "\\" yazmalısınız.

Bilginize:

Tek ve çift tırnaklı PHP dizeleri içinde tersbölü karakteri özel olarak ele alınır. Bir \ ile eşleşen \\ düzenli ifadesi, PHP kodu içinde "\\\\" veya '\\\\' olarak belirtilmelidir.

Bir şablon PCRE_EXTENDED seçeneği ile derlenmişse kalıp içindeki (bir karakter sınıfının dışında kalan) boşluk karakterleri ve bir karakter sınıfının dışındaki bir "#" karakteri ile sonraki satırsonu karakteri arasındaki karakterler yok sayılır. Bir boşluk veya "#" karakterini şablonun parçası haline getirmek için, karakter tersbölü ile öncelenir.

Tersbölü karakterinin ikinci kullanımı, basılamayan karakterleri şablon içinde görünür kılmak içindir. İkil sıfırın şablonu sonlandırması dışında basılamayan karakterlerin görünümü ile ilgili bir kısıtlama yoktur. Fakat, bir şablon, bir metni düzenleyerek hazırlanıyorsa aşağıdaki önceleme dizilimlerini kullanmak, ifade ettikleri ikil karakterleri kullanmaktan daha kolaydır:

\a
sesli uyarı, yani BEL karakteri (onaltılık 07)
\cx
"CTRL-x"; buradaki x yerine herhangi bir karakter konabilir
\e
kaçış karakteri (onaltılık 1B)
\f
sayfa ileri (onaltılık 0C)
\n
satırsonu (onaltılık 0A)
\p{xx}
xx özellikli bir karakter, daha fazla bilgi için bkz. unicode özellikleri.
\P{xx}
xx özelliksiz bir karakter, daha fazla bilgi için bkz. unicode özellikleri.
\r
satırbaşı (onaltılık 0D)
\R
satırsonu:\n, \r ve \r\n ile eşleşir
\t
sekme (onaltılık 09)
\xhh
onaltılık kodu hh olan karakter
\ddd
sekizlik kodu ddd olan karakter veya bir geriye gönderim

"\cx" diziliminin en hassas etkisi şöyledir: "x" bir küçük harf ise büyük harfe dönüştürülür ve karakterin 6. biti (onaltılık 40) evrilir. Böylece, "\cz" dizilimi onaltılık 1A haline gelirken "\c{" onaltılık 3B ve "\c;" onaltılık 7B haline gelir.

"\x" dizilimden sonra en fazla iki onaltılık rakam okunur (harfler büyük veya küçük olabilir). UTF-8 kipinde, "\x{...}" gösterimine izin verilir; kaşlı ayraçların arasına yazılan onaltılık sayı UTF-8 karakterin kodu olarak yorumlanır. Özgün onaltılık önceleme dizilimi \xhh, eğer karakterin kodu 127'den büyükse iki baytlık bir UTF-8 karakteri ile eşleşecektir.

"\0" dizilimden sonra en fazla iki sekizlik rakam okunur. Her iki durumda da, iki rakamdan azı varsa olanlar kullanılır. Böylece, "\0\x\07" dizilimi iki ikil sıfırdan sonra bir BEL karakteri olarak yorumlanır. Eğer sekizlik gösterimin hemen ardından sekizlik rakam olarak yorumlanabilecek bir karakter geliyorsa ilk sıfırdan sonra mutlaka iki sekizlik rakam kullanın.

Tersbölünün hemen ardından 0 haricinde bir rakam gelmesi durumunda durum biraz karışır. Bir karakter sınıfının dışında, PCRE o rakamı ve diğer rakamları bir onluk sayı olarak okur. Eğer sayı 10'dan küçükse veya evvelce belirtilmiş yakalayan alt şablonlar varsa dizilimin tamamı bir geriye gönderim olarak ele alınır. İkinci durumun nasıl çalıştığı aşağıda parantezli alt şablonların açıklamasında anlatılmıştır.

Bir karakter sınıfının içinde veya evvelinde yakalayan alt şablonlar bulunmayan 9'dan büyük bir onluk sayı varlığında PCRE tersbölüden sonra en fazla üç sekizlik rakam okur ve değerin en önemsiz 8 bitinden tek bir bayt üretir. Daha sonraki rakamlar karakterlerin kendileri olarak ele alınır. Örnekler:

\040
Boşluk karakterini ifade etmenin bir başka yolu.
\40
40'tan az yakalayan alt şablon varlığında bu da aynısı.
\7
Daima geriye gönderim olarak yorumlanır.
\11
Duruma göre, bir geriye gönderim olabileceği gibi sekme karakteri olarak da yorumlanabilir.
\011
Daima bir sekme karakteridir
\0113
Sekme karakterinden sonra "3" var.
\113
Sekizlik kodu 113 olan karakter (99'dan fazla geriye gönderim olamayacağı için).
\377
Tamamı 1 bitten oluşan bir bayt.
\81
Duruma göre, bir geriye gönderim olabileceği gibi ikil sıfırın ardından gelen "8" ve "1" karakterleri de olabilir.

100'den büyük sekizlik değerlerin başına sıfır konmamalıdır, çünkü üç sekizlik rakamdan fazlası sekizlik sayının rakamları olarak ele alınmamaktadır.

Tek bir bayt değerini tanımlayan tüm dizilimler karakter sınıflarının içinde de dışında da kullanılabilir. Ek olarak, bir karakter sınıfının içinde, "\b" dizilimi bir tersbölü karakteri (onaltılık 08) olarak yorumlanır. Karakter sınıfının dışında ise anlamı farklıdır (aşağıya bakınız).

Tersbölünün üçüncü kullanımı soysal karakter türlerini belirtmek içindir:

\d
Herhangi bir onluk rakam
\D
Bir onluk rakam olmayan herhangi bir karakter
\h
Herhangi bir yatay boşluk karakteri
\H
Bir yatay boşluk karakteri olmayan herhangi bir karakter
\s
Herhangi bir boşluk karakteri
\S
Bir boşluk karakteri olmayan herhangi bir karakter
\v
Herhangi bir düşey boşluk karakteri
\V
Bir düşey boşluk karakteri olmayan herhangi bir karakter
\w
Herhangi bir "sözcük" karakteri
\W
Bir "sözcük" karakteri olmayan herhangi bir karakter

Her önceleme dizilimi çifti karakter kümesinin tamamını iki ayrı küme haline getirir. Belirtilen her karakter sadece ve sadece bir çift ile eşleşir.

"Boşluk" karakterleri HT (9), LF (10), FF (12), CR (13) ve boşluktur (32). Bununla birlikte, yerele özgü eşleştirme gerçekleşiyorsa, 128-255 aralığındaki kodlar sahip karakterler de boşluk karakterleri olarak kabul edilebilir, örneğin, NBSP (A0).

Bir "sözcük" karakteri herhangi bir harf, rakam veya alt çizgi karakteri olabilir, yani, bir Perl sözcüğünün parçası olabilen her karakter bir "sözcük" karakteri olabilir. Harflerin ve rakamların tanımı PCRE'nin karakter tablosu tarafından denetlenir ve eşleştirme yerele özgü yapılıyorsa bu tanım değişebilir. Örneğin "tr" yerelindeki 128'den büyük karakter koduna sahip "çğıöşü" gibi karakterler \w ile eşleşir.

Karakter türündeki bu dizilimler karakter sınıflarının içinde veya dışında bulunabilir. Her biri uygun türdeki bir karakterle eşleşir. Eğer karakter eşleştirmesinde eşleşmeye konu dizgenin sonuna gelinmişse hiçbir karakter eşleşmeyeceğinden işlem başarısız olacaktır.

Tersbölünün dördüncü kullanımı bazı basit tezleri belirtmek içindir. Bir tez, eşleşmeye konu dizgenin hiçbir karakterini harcamaksızın belli bir noktada yerine getirilmesi gereken bir koşul belirtir. Daha karmaşık tezler için alt şablonların kullanımı aşağıda açıklanmıştır. Tez işleçleri şunlardır:

\b
Sözcük sınırlarıyla eşleşme işleci
\B
Sözcük içi eşleşme işleci
\A
Eşleşmeye konu dizgenin başlangıcı ile eşleşme işleci (çok satırlı kipten bağımsız)
\Z
Eşleşmeye konu dizgedeki satırsonu karakterinin öncesiyle eşleşme işleci (çok satırlı kipten bağımsız)
\z
Eşleşmeye konu dizgenin sonu ile eşleşme işleci (çok satırlı kipten bağımsız)
\G
eşleşmeye konu dizgede eşleşme başlangıcını belirtme işleci

Bu tez işleçleri "\b" hariç karakter sınıfları içinde görünmezler. "\b" işleci karakter sınıfları içinde özel bir anlama sahiptir ve tersbölü karaterini simgeler.

Eşleşmeye konu dizge içinde geçerli karakterin \w işleci ile ve önceki karakterin \W işleci ile eşleştiği nokta sözcük sınırının başlangıcını; geçerli karakterin \W işleci ile ve önceki karakterin \w işleci ile eşleştiği nokta ise sözcük sınırının bitişini belirler.

\A, \Z ve \z tez işleçleri, seçeneklerle belirlenen şekilde dizgenin en başı ve dizgenin en sonu ile eşleşen geleneksel şapka ve dolar imli işleçlerden (çıpalar altında açıklanmıştır) farklı olup PCRE_MULTILINE veya PCRE_DOLLAR_ENDONLY seçeneğinden etkilenmezler. \Z ile \z arasındaki fark \Z işlecinin dizgenin son karakteri olan satırsonu karakterinin öncesiyle eşleşmesi, \z işlecinin ise sadece dizge sonu ile eşleşmesidir.

\G savı, sadece, geçerli eşleşme konumu eşleşmenin başlangıç noktasında (preg_match() işlevinin başlangıç bağımsız değişkeni ile belirtilen noktada) olduğu takdirde doğru olacaktır. başlangıç sıfırdan farklı olduğu durumda \G işleci \A işlecinden farklıdır.

\Q ve \E işleçleri şablon içindeki düzenli ifade işleçlerini geçersiz kılmak için kullanılabilmektedir. Örneğin, \w+\Q.$.\E$ düzenli ifadesi dizge sonuna demirlenmiş .$. karakterleriyle ve bunların öncesindeki bir veya daha fazla sayıda sözcük karakteriyle eşleşecektir. Bu, ayraçların davranışını değiştirmez. Örneğin, #\Q#\E#$ düzenli ifadesi, ikinci # şablonun sonunu imlediğinden ve \E# geçersiz değiştirici olarak yorumlandığından geçersizdir.

\K işleci eşleşme başlangıcını sıfırlamak için kullanılabilmektedir. Örneğin, foo\Kbar şablonu, "foobar" ile eşleşir, fakat "bar" ile eşleştiğini raporlar. \K işlecinin kullanımı zaten eşleştirilmiş alt dizge ile etkileşmez. Örneğin, (foo)\Kbar şablonu "foobar" ile eşleşirken eşleşen ilk alt dizge "foo" olacaktır.

add a note

User Contributed Notes 6 notes

up
53
mike at eastghost dot com
12 years ago
"line break" is ill-defined:

-- Windows uses CR+LF (\r\n)
-- Linux LF (\n)
-- OSX CR (\r)

Little-known special character:
\R in preg_* matches all three.

preg_match( '/^\R$/', "match\nany\\n\rline\r\nending\r" ); // match any line endings
up
8
Wirek
6 years ago
Significantly updated version (with new $pat4 utilising \R properly, its results and comments):
Note that there are (sometimes difficult to grasp at first glance) nuances of meaning and application of escape sequences like \r, \R and \v - none of them is perfect in all situations, but they are quite useful nevertheless. Some official PCRE control options and their changes come in handy too - unfortunately neither (*ANYCRLF), (*ANY) nor (*CRLF) is documented here on php.net at the moment (although they seem to be available for over 10 years and 5 months now), but they are described on Wikipedia ("Newline/linebreak options" at https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions) and official PCRE library site ("Newline convention" at http://www.pcre.org/original/doc/html/pcresyntax.html#SEC17) pretty well. The functionality of \R appears somehow disappointing (with default configuration of compile time option) according to php.net as well as official description ("Newline sequences" at https://www.pcre.org/original/doc/html/pcrepattern.html#newlineseq) when used improperly.
A hint for those of you who are trying to fight off (or work around at least) the problem of matching a pattern correctly at the end ($) of any line in multiple lines mode (/m).
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
// C 3 p 0 _
$pat1='/\w$/mi'; // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi'; // Slightly better
$pat3='/\w\R?$/mi'; // Somehow disappointing according to php.net and pcre.org when used improperly
$pat4='/\w(?=\R)/i'; // Much better with allowed lookahead assertion (just to detect without capture) without multiline (/m) mode; note that with alternative for end of string ((?=\R|$)) it would grab all 7 elements as expected
$pat5='/\w\v?$/mi';
$pat6='/(*ANYCRLF)\w$/mi'; // Excellent but undocumented on php.net at the moment (described on pcre.org and en.wikipedia.org)
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
$t=preg_match_all($pat6, $str, $m6);
echo
$str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
.
"\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
.
"\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
.
"\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
.
"\n5 !!! $pat5 ($s): ".print_r($m5[0], true)
.
"\n6 !!! $pat6 ($t): ".print_r($m6[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 and $pat4 (\R), $pat5 (\v) and altered newline option in $pat6 ((*ANYCRLF)) - for some applications at least.

/* The code above results in the following output:
ABC ABC

123 123
def def
nop nop
890 890
QRS QRS

~-_ ~-_
1 !!! /\w$/mi (3): Array
(
[0] => C
[1] => 0
[2] => _
)

2 !!! /\w\r?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)

3 !!! /\w\R?$/mi (5): Array
(
[0] => C

[1] => 3
[2] => p
[3] => 0
[4] => _
)

4 !!! /\w(?=\R)/i (6): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
)

5 !!! /\w\v?$/mi (5): Array
(
[0] => C

[1] => 3
[2] => p
[3] => 0
[4] => _
)

6 !!! /(*ANYCRLF)\w$/mi (7): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
[6] => _
)
*/
?>
Unfortunately, I haven't got any access to a server with the latest PHP version - my local PHP is 5.3.8 and my public host's PHP is version 5.2.17.
up
4
Anonymous
4 years ago
A non breaking space is not considered as a space and cannot be caught by \s.

it can be found with :

- [\xc2\xa0] in utf-8
- \x{00a0} in unicode
up
10
grigor at the domain gatchev.info
12 years ago
As \v matches both single char line ends (CR, LF) and double char (CR+LF, LF+CR), it is not a fixed length atom (eg. is not allowed in lookbehind assertions).
up
-1
tharabar at gmail dot com
4 years ago
Required to use \007 instead of \a
up
-4
Wirek
6 years ago
Note that there are (sometimes difficult to grasp at first glance) nuances of meaning and application of escape sequences like \r, \R and \v - none of them is perfect in all situations, but they are quite useful nevertheless. Some official PCRE control options and their changes come in handy too - unfortunately neither (*ANYCRLF), (*ANY) nor (*CRLF) is documented here on php.net at the moment (although they seem to be available for over 10 years and 5 months now), but they are described on Wikipedia ("Newline/linebreak options" at https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions) and official PCRE library site ("Newline convention" at http://www.pcre.org/original/doc/html/pcresyntax.html#SEC17) pretty well. The functionality of \R appears somehow disappointing (with default configuration of compile time option) according to php.net as well as official description ("Newline sequences" at https://www.pcre.org/original/doc/html/pcrepattern.html#newlineseq).

A hint for those of you who are trying to fight off (or work around at least) the problem of matching a pattern correctly at the end ($) of any line in multiple lines mode (/m).
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
// C 3 p 0 _
$pat1='/\w$/mi'; // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi';
$pat3='/\w\R?$/mi'; // Somehow disappointing according to php.net and pcre.org
$pat4='/\w\v?$/mi';
$pat5='/(*ANYCRLF)\w$/mi'; // Excellent but undocumented on php.net at the moment
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
echo
$str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
.
"\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
.
"\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
.
"\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
.
"\n5 !!! $pat5 ($s): ".print_r($m5[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 (\R), $pat4 (\v) and altered newline option in $pat5 ((*ANYCRLF)) - for some applications at least.

/* The code above results in the following output:
ABC ABC

123 123
def def
nop nop
890 890
QRS QRS

~-_ ~-_
1 !!! /\w$/mi (3): Array
(
[0] => C
[1] => 0
[2] => _
)

2 !!! /\w\r?$/mi (5): Array
(
[0] => C
[1] => 3
[2] => p
[3] => 0
[4] => _
)

3 !!! /\w\R?$/mi (5): Array
(
[0] => C

[1] => 3
[2] => p
[3] => 0
[4] => _
)

4 !!! /\w\v?$/mi (5): Array
(
[0] => C

[1] => 3
[2] => p
[3] => 0
[4] => _
)

5 !!! /(*ANYCRLF)\w$/mi (7): Array
(
[0] => C
[1] => 3
[2] => f
[3] => p
[4] => 0
[5] => S
[6] => _
)
*/
?>
Unfortunately, I haven't got any access to a server with the latest PHP version - my local PHP is 5.3.8 and my public host's PHP is version 5.2.17.
To Top