Odkrywanie tajemnicy zaczęło się od informacji, że instrukcja show czasami generuje komunikaty E_NOTICE w metodzie obsługującej zamknięcie tagu. Za pomocą stosownych technik wywiadowczych doszedłem do wniosku, że taki komunikat nijak nie może w takim kodzie powstać, bo wszystko jest pięknie zsynchronizowane. Ale pewnego dnia pięknego, gdy słońce zza bloku wyjrzało, stało się, że podczas pisania własnego szablonu, także ową wiadomość ujrzałem na swym ekranie. Analizowałem kompilator wzdłuż i wszerz. Szablon był mniej więcej taki:
OP zezwala na niezamykanie tagów instrukcji, gdyż w tym przypadku odpowiednią informację o sposobie przetwarzania zdobywa z jej procesora. Dopiero, gdy mamy do czynienia z tagami niezdefiniowanymi, które musimy sobie sami poprzetwarzać, wymagana jest pełna poprawność. Otóż cały myk w powyższym kodzie polegał na tym, że miałem instrukcję opfUrl, a z rozpędu wpisałem nieistniejącą url. OPT potraktował to jako znacznik niezdefiniowany, nie znalazł slasha na końcu i otworzył węzeł. Następnie, zupełnie niespodziewanie, zakończył go... znacznikiem {/section}, choć w teorii powinien poszukiwać {/url} i zasygnalizować jego brak. Zamiast spodziewanego {/section}, procesor sekcji dostał na wejściu {/show}, a że nie wykonał wcześniej odpowiednich operacji, PHP zgłosił komunikat E_NOTICE. Ot, i cała historia.
W parserach XML-opodobnych wykonanie zabezpieczenia przed tym jest niejako mechaniczne. Wystarczy zwykły stos i odkładanie/dokładanie na elementów. OPT, ze względu na obsługę alternatywnych bloków kodu w tagach: {tag}...{tagelse}...{/tag}, musiał zastosować nieco inny format budowy drzewa, w którym naturalniejsza stała się sytuacja opisana powyżej. Oczywiście naturalizm, a wygoda użytkownika (oraz moje zdrowie psychiczne) to zupełnie inne sprawy i w OPT 1.0.0-RC3 odpowiednie zabezpieczenie będzie kontrolowało kolejność zamykania znaczników.














