PHP regex segfault önlemek gerekir

4 Cevap php

Neden aşağıdaki segfault yapar, ve bunu nasıl önleyebilirsiniz?

<?php

$str = ' <fieldset> <label for="go-to">Go to: </label>  ' 
       . str_repeat(' ', 10000) 
       . '<input type="submit" value="Go" /> </fieldset> </form>';

preg_match_all("@
</?(?![bisa]\b)(?!em\b)[^>]*> # starting tag, must not be one of several inline tags
(?:[^<]|</?(?:(?:[bisau]|em|strong|sup)\b)[^>]*>)* #allow text and some inline tags
[\?\!\.]+
@ix", $str, $matches);

?>

Ben .... bunun için yığın taşmasına bekleyin .... bir neden inanıyorum.

EDIT:

Yukarıdaki basitleştirilmiş versiyonu sorunu gösteren kalıptır. Daha tam bir versiyonu:

@
</?(?![bisa]\b)(?!em\b)[^>]*> # starting tag, must not be one of several inline tags
(?:[^<]|</?(?:(?:[bisau]|em|strong|sup)\b)[^>]*>)* # continue, allow text content and some inline tags

# normal sentence ending
[\?\!\.]+ # valid ending characters -- note elipses allowed
(?<!\b[ap]m\.)(?<!\b[ap]\.m\.)(?<!digg this\!)(?<!Stumble This\!) # disallow some  false positives that we don't care about
\s*
(?:&apos;|&\#0*34;|'|&lsquo;)?\s* # closing single quotes, in the unusual case like "he said: 'go away'".
(?:"|&quot;|&\#0*34;|&\#x0*22;|&rdquo;|&\#0*8221;|&\#x0*201D;|''|``|\xe2\x80\x9d|&\#0*148;|&\#x0*94;|\x94|\))?\s* # followed by any kind of close-quote char
(?=\<) # should be followed by a tag.
@ix

Amacı, geçerli bir İngilizce cümle biten benzediğini sona görünen html blokları bulmak. Ben bu yöntemi (bir makale vücut gibi) 'içerik' metin ve (gezinti öğeleri gibi yani) 'düzen' metin arasındaki farkı anlatma konusunda çok iyi olduğunu bulduk. Beyaz boşluk büyük bir miktarı etiketleri arasında varsa Bazen Ancak, darbeler.

4 Cevap

Ben denemek istiyorum ilk şey tüm nicelik iyelik ve tüm grupların atomik yapıyor:

"@</?+(?![bisa]\b)(?!em\b)[^>]*+>
(?>[^<]++|</?+(?>(?>[bisau]|em|strong|sup)\b)[^>]*+>)*+
[?!.]+
@ix"

Ben Jeremy'nin hakkını düşünüyorum: o regex motoru olası yararlar yapmak kurtarmak için sahip olduğu tüm devlet bilgi bulunuyor, per se sizi öldürüyor geriye değil. Regex hiç sarfınazar varsa, yine başarısız olacak şekilde inşa edilecek gibi görünüyor. Yani iyelik nicelik ve atom grupları kullanımı ve tüm bu gereksiz bilgileri kaydetme zahmet etmeyin.

EDIT: cümle bitmeyen noktalama için, ikinci satırda başka bir alternatif ekleyebilirsiniz izin:

(?>[^<?!.]++|(?![^?!.\s<]++<)[?!.]++|</?+(?>(?>[bisau]|em|strong|sup)\b)[^>]*+>)*+

Onlar öğesi olmayan son boşluk karakterleri değilseniz eklenmesi dedi karakterlerden birini veya daha fazlasını eşleşir.

Bu hala istediğiniz ne yapıyor?

</?(?![bisa]\b)(?!em\b)[^>]*> # starting tag, must not be one of several inline tags
(?:(?>[^<\?\!\.]*)|</?(?:(?:[bisau]|em|strong|sup)\b)[^>]*>)* #allow text and some inline tags
[\?\!\.]+

Düzenli ifade Backtracking büyük miktarda neden olur. Ortada 10000 karakterleri ile, oldukça dağınık ve yavaş olacaktı. Yine de, ben çökmesine beklemek olmaz ...!

PHP bile yeni sürümleri kademeli arıza bilinen sorunlar var PCRE'nin 7.0 ile birlikte olduğundan oldukça eminim. Ben teknik bir PCRE'nin sorunu değil, PHP ile bir sorunu olduğu gibi sorunu düzeltme üzerinde herhangi bir niyetleri olduğunu sanmıyorum.

Eğer başarmak için ne çalışıyorsunuz bize söylersen senin en iyi bahis alternatif bir ifade yazmak denemek olacaktır.

Söz konusu hata: http://bugs.php.net/bug.php?id=40909