Komputery, Windows i masa kompletnego bałaganu. Tak, to mój dziennik.

ktos.jogger


Search & Replace

21 sierpnia 2007, 20:38:24. Kodowanie , 1.

Przed momentem napisałem sobie funkcyjkę, która musi usuwać znak z początku i końca stringa, który jest dodawany przez inną funkcyjkę. A następnie po testach użyłem Search & Replace w moim edytorze i wszystkie wywołania starej funkcji zostały zastąpione przez nową funkcję. Jednak nie wpadłem na to, że wywołanie starej funkcji wewnątrz nowej także zostanie zmienione...

I tak przed momentem byłem świadkiem ciągłych padów Apache, a sam dziwiłem się co u licha się może dziać. Ale jak się ma nie dziać, skoro przepełniałem stos robiąc coś takiego:

private function _mydbescape($str) { $str = $this->_mydbescape($str); return substr($str, 1, strlen($str) -2); }

Aczkolwiek dlaczego padał Apache, a nie pojawiał się krytyczny błąd PHP albo coś w tym rodzaju?

Komentarze

  1. Dot
    21 sierpnia 2007 20:40:19

    Nie mów, że na Leii to psułeś? :D

  2. Marcin "Ktos"
    21 sierpnia 2007 20:41:33

    Nie, lokalnie. Nawet kompa zrestartowałem by wykluczyć problem tam, zamiast przyjrzeć się mojemu kodowi dokładnie.

    Ale przysiągłbym, że zakomentowanie wywołania funkcji za pierwszym razem nie spowodowało tego, że wszystko zaczęło działać, dlatego doszedłem po dłuższym debugowaniu.

  3. Michał Moroz
    21 sierpnia 2007 20:43:00

    Strzelam – limit pamięci skryptu w PHP odnosi się tylko do zaalokowanej przestrzeni a nie do rekursywnych wywołań funkcji. Po chwili albo Apache samo się ubijało albo ulimit je ubijał.

  4. Marcin "Ktos"
    21 sierpnia 2007 20:59:10

    Michał, możesz mieć rację, bo limity mam stosunkowo restrykcyjne (8 MB na skrypt, 30 sekund czasu wykonania). Ale jak dla mnie niezapobieganie wyłożeniu się Apache w takiej sytuacji to absolutny błąd interpretera PHP.

    Przeszukałem bugs.php.net i znalazłem kilkanaście raportów (aczkolwiek do wersji 4.x-5.0RC tylko) tego samego zawsze z jednym rozwiazaniem: „Won’t fix”. No bo:

    PHP does not do infinite recursions, and there is no way to protect or check for this without making things much slower.

    Zatem mamy ładną metodę ataku na czyjeś serwery jeżeli używają mod_php…

  5. Michał Moroz
    21 sierpnia 2007 21:05:53

    Ośmielam się nie zgodzić z ostatnim zdaniem – możliwość zdalnego wykonywania kodu php ma znacznie niebezpieczniejsze konsekwencje, niż ubicie serwera. A nie wyobrażam sobie po prawdzie innej możliwości wykonania nieskończonej rekursji, wyłączywszy pomyłkę programisty.

    Z drugiej strony, C także nie sprawdza, czy nieskończona rekursja prowadzi do czegoś, czy nie… Sądzę, że to nie język powinien za to odpowiadać. :)

  6. Marcin "Ktos"
    21 sierpnia 2007 21:10:27

    Fakt (zresztą sam nie znam języka sprawdzającego nieskończoną rekursję) jednak – tworząc analogię – program w C przepełniając stos z takiego powodu wyłoży się sam, a nie system operacyjny jak to robi z Apache mod_php.
    Chyba.

    Poza tym już PHP jest mimo wszystko interpretowany i może to kontrolować, w przypadku C sprawa wygląda inaczej.

  7. Michał Moroz
    21 sierpnia 2007 21:19:39

    Gdyby php był osobnym procesem pod przewodnictwem Apache, to zgadzam się, Apache mógłby ubijać go, ile chce. I pewnie tak robi poprzez CGI. Jednak mod_php jest częścią programu Apache – nie widzę sposobu, w jaki sposób serwer miałby kontrolować, czy wtyczka już się wywala, czy jeszcze nie, dopóki sama wtyczka tego mu nie powie.

    Myślę jednak, że recursion_limit byłoby łatwo wykonać – najprostsze rozwiązanie wymagałoby jednego inta. Ale podejście ludzi z PHP też mnie nie dziwi – to nie oni mają się zajmować sprawdzaniem, czy user nie popełnił błędu. ;)

  8. Michał Górny
    21 sierpnia 2007 21:39:04

    > program w C przepełniając stos z takiego powodu wyłoży się sam, a nie system operacyjny

    …o ile nie jest to Windows q ;.

    Wniosek: lepiej używać (Fast)CGI. Wniosek z wniosku: Na cholerę używać więc takiej kobyły jak Apache? Wniosek z wniosku: a PHP i tak ssie w trybie CGI, więc po co go w ogóle używać, skoro ssie w tak wielu aspektach? q ;.

  9. Marcin "Ktos"
    21 sierpnia 2007 21:58:40

    Teraz muszę już wskazywać do którego z Michałów się odnoszę :-)

    Michał Górny: Używałem bardzo długi czas serwera o nazwie Xitami, ale do Apache zmusiły mnie dwie rzeczy – dziwne zachowania Xitami w niektórych aspektach (do dziś nie wiem dokładnie o co chodziło, fakt, że niektóre skrypty nie działały poprawnie) oraz mod_rewrite.

    A PHP mam zamiar jednak porzucać powoli na rzecz ASP.NET (i jego Yellow-screen-of-death) ;-)

  10. coldpeer
    22 sierpnia 2007 01:44:21

    ASP.NET? To już lepiej Python i Django, bądź Ruby i Rails.

  11. Michał Górny
    22 sierpnia 2007 09:53:00

    Perl i Catalyst! q ;.

  12. Marcin "Ktos"
    22 sierpnia 2007 09:59:35

    C w trybie CGI!

    BTW Ja teraz potrzebuję języków obiektowych – niedawno potrzebowałem sprawdzić czy przekazana do skryptu wartość „referer” zaczyna się od adresu witryny. I chciałem to zrobić tak: if ($referer.StartsWith(site_url())) po czym sobie uświadomiłem, że PHP to nie .NET i tutaj string nie jest obiektem i należy użyć do tego „normalnie” funkcji ;-)
    Aczkolwiek ten, co wymyślał koncepcję nazewnictwa metod/pól w JavaScript niech się pali na stosie.

Zostaw komentarz

W komentarzach dozwolona jest składnia Markdown do formatowania.