Modül dersleri (4/4)
Geri izleme: genel bakış
Açgözlü bir nicelik belirteci "aşırıya kaçtığında", motor geri izleme gerçekleştirir: geri adım atar, başka bir konfigürasyonu dener, yeniden dener. Basit desenlerde görünmez; kötü yazılmış kalıplarda üstel hale gelebilir ve tarayıcıyı saniyeler boyunca dondurun. ReDoS'un köküdür (Normal Hizmet Reddi ifadesi).
Pattern: .*\d
Sample: abc123def
Steps:
1. .* consumes everything: "abc123def"
2. \d fails (end of string).
3. Backtrack: .* drops 'f' -> "abc123de", \d fails on 'f'.
4. Backtrack: .* drops 'ef' -> "abc123d", \d fails on 'e'.
5. ... and so on until \d finds a digit: match = "abc123" + "?"... actually
the pattern matches "abc123" because .* leaves "def" and \d looks at '3'? No: the
backtrack continues and .* ends up being "abc12", \d=3. Final match: "abc123".Motor her zaman oraya varır, ancak açgözlü bir niceleyici şunları içeriyorsa
başka bir açgözlü niceleyici (ör. (a+)+), konfigürasyonların sayısı
denemek patlayabilir.
Felaket desenleri
Pattern: (a+)+b
Sample: aaaaaaaaaaaaaaaaaaaaaTakip yok b → model başarısız oluyor, ancak oraya ulaşmak için motor her yolu dener
a'lerin olası bölümü. Üstel büyüme: 30 as ile şunları yapabilirsiniz:
saatlerce bekleyin.
Geri izlemenin ve ReDoS'un tehlikeleri
Bir model örtüşen veya iç içe geçmiş niceleyiciler içerdiğinde (örneğin (a+)+), motor başarısız olmadan önce üstel sayıda yolu değerlendirir. Genel joker karakterlerin karakter sınıflarını hariç tutacak şekilde değiştirilmesi, geri izleme yollarını önemli ölçüde azaltır.
Deneyin
Metindeki her geçiş için köşeli parantez içindeki içeriği çıkarın. Daha sonraki kapanışlara atlamaktan kaçınmak için niceleyicinin tembel versiyonunu kullanın.
İpucu göster
\\[.*?\\] ilk kapanışta durur ]: ağır geri izleme olmaz.
3 denemeden sonra çözüm mevcut
Alıştırmayı gözden geçirin
Yolun boşluksuz karakterleri için isteğe bağlı "s" ve "\\S+" niceleyicisini kullanarak metindeki her "http://..." veya "https://..." URL'sini bulun.
İpucu göster
https? 'http' ve ardından isteğe bağlı 's' anlamına gelir. Sonra //, ardından \\S+ (boşluksuz).
3 denemeden sonra çözüm mevcut
Ek zorluk
Match strings enclosed in double quotes, avoiding excessive backtracking by using the negated class `[^"]*` instead of `.*`.
İpucu göster
Replace the dot with the negated class [^"] to restrict the engine's backtracking paths.
3 denemeden sonra çözüm mevcut