[ Pobierz całość w formacie PDF ]
484.). W linii 746. kończymy blok warunkowy if z linii 707., który sprawdzał, jakiego typu odpowiedzi udzielić użytkownikowi. Kończymy tam również główny program. u lini n n . lini u ni dn l n u n HTT . d n n u i linii . a a e a a a e a W programie występuje kilka miejsc, w których wysyłamy lub przetwarzamy pliki określone w formularzu lub konfiguracji. Jak wspomnieliśmy już wcześniej, z punktu widzenia bezpieczeństwa systemu jest niezwykle ważne, aby upewnić się, że pliki te pochodzą z właściwego katalogu, którego nie dotyczą ograniczenia (ustawiane zwykle przez administratora programu). W tym celu procedura wykorzystuje dwie globalne tablice: _ _ i _ _ . 754 sub valid_directory { Linię 754. rozpoczynamy od deklaracji i nazwy procedury. 756 local ($filename) = $_[0]; 757 local ($allowed_path, $restricted_path); Procedura jest wywoływana z parametrem zawierającym nazwę pliku do sprawdzenia. W linii 756. przypisujemy ją do lokalnej zmiennej e a e. Linia 757. deklaruje dwie dodatkowe zmienne lokalne używane wewnątrz procedury. 759 local($valid_dir) = 0; f& a Kolejno deklarujemy znacznik a _ i inicjujemy jego wartość wpisując zero. Zmienna ta posłuży do śledzenia poprawności lokalizacji pliku w różnych miejscach procedury. Zaczynamy od przypuszczenia, że plik nie znajduje się w prawidłowym ka- talogu. 760 if ($ALLOWED_ATTACH_DIRS[0] =~ /^all$/i) { $valid_dir = 1 } 761 else { 762 foreach $allowed_path (@ALLOWED_ATTACH_DIRS) { 763 $valid_dir = ($filename =~ /^$allowed_path/); 764 last if $valid_dir; 765 } 766 } Najpierw musimy sprawdzić, czy plik znajduje się w dozwolonym katalogu. W linii 760. sprawdzamy, czy pierwszym elementem tablicy LL D_ TT H_Dl jest all, w tym przypadku ustawiamy wartość lid_di na 1. Jeśli nie w linii 762. rozpo- czynamy pętlę przeglądającą kolejne elementy LL D_ TT H_Dl . Linia 763. jest trochę zagmatwana służy do sprawdzenia, czy nazwa pliku zawiera na początku ścieżkę z tablicy podstawiając pod lid_ i wynik porównania (0 lub 1). W linii 764. przerywamy pętlę, jeśli tylko zmienna lid_di osiągnęła już wartość 1 (innymi słowy jeśli odnalezliśmy już ścieżkę dostępu do pliku w tablicy LL D_ TT H_Dl ). 768 foreach $restricted_path (@RESTRICTED_ATTACH_DIRS) { 769 $valid_dir = ($filename !~ /^$restricted_path/); 770 last if !$valid_dir; 771 } Teraz możemy wykonać nieco inny test w odniesieniu do tablicy T l T D_ TT H_Dl (jeśli takową zdefiniowano). W linii 768. rozpoczynamy pętlę przegląda- jącą jej elementy. Tym razem sprawdzamy, czy nazwa pliku nie zaczyna się od ścieżki wyszczególnionej w tablicy. Podobnie jak poprzednio, pętla zostaje przerwana, jeśli zmienna lid_di zawiera 0. (Warto porównać te linie z liniami 763. i 764. i spróbo- wać odpowiedzieć na pytanie, dlaczego ich działanie jest odwrotne). 772 return $valid_dir; 773 } W linii 773. zwracamy ostateczną wartość zmiennej lid_di i kończymy blok kodu procedury. e e a e a e a W niniejszej książce znajdziemy różne sposoby zgłaszania błędów. Większość z nich korzysta z procedury bibliotecznej error. Jej wykorzystanie jest oczywiście wyłącznie sprawą własnych preferencji. Program używa lokalnej procedury, a nie procedury z ze- wnętrznej biblioteki, aby móc elastyczniej obsługiwać różne rodzaje błędów. 780 sub error { Procedurę rozpoczynamy od deklaracji jej nazwy. 784 local($error) = $_[0]; 785 print "Content-type: text/html\n\n"; a . f& e a e a a e . Wywołanie procedury zawiera komunikat błędu jako pierwszy parametr. Przepisujemy go do zmiennej lokalnej e (w linii 785.) i generujemy odpowiedni nagłówek strony. a a e a W procedurę wbudowano specjalną obsługę błędu dotyczącego brakujących pól. 790 if ($error eq 'missing_required_fields') { 795 $CONFIG{'error_fields'} = "\n"; 796 foreach $missing_required_field (@missing_required_fields) { 797 if ($ALT_NAME{$missing_required_field}) { 798 $CONFIG{'error_fields'} .= "$ALT_NAME{$missing_required_field}\n"; 799 } 800 else { 801 $CONFIG{'error_fields'} .= "$missing_required_field\n"; 802 } 803 } 804 $CONFIG{'error_fields'} .= ""; W linii 790. sprawdzamy, czy zgłoszono błąd brakujących pól. Jeśli tak, w liniach 795. do 804. ustawiamy zmienną e _ e formularza tak, aby zawierała listę brakujących pól. (Skorzystamy z niej w pliku wzorca). Linia 795. rozpoczyna nadawanie wartości zmiennej _ i ld znacznikiem HTML-owym otwierającym nie numerowaną listę. W linii 796. rozpoczynamy pętlę przeglądającą poszczególne brakujące pola (które za- pamiętane są w zmiennej i in _ ui d_ i ld ). W linii 797. sprawdzamy, czy dla przeglądanego pola istnieje nazwa alternatywna. Jeśli tak, linia 798. dodaje do _ i ld element listy zawierający nazwę alternatywną. Jeśli nie, posługujemy się po prostu nazwą zmiennej. Po zakończeniu pętli dodajemy znacznik HTML-owy zamyka- jący listę. 808 if ($CONFIG{'error_html_template'} 809 && &valid_directory($CONFIG{'error_html_template'})) { 810 if (!&parse_template($CONFIG{'error_html_template'}, *STDOUT)) { 811 $error = "Can't open $CONFIG{'error_html_template'} ($!)."; 812 } 813 else { exit } 814 } Linie 808. i 809. służą do sprawdzenia, czy został określony wzorzec komunikatu. Jeśli tak, linia 810. podejmuje próbę przetworzenia go, w przypadku niepowodzenia zmieniając odpowiednio komunikat o błędzie. (Teoretycznie moglibyśmy wywołać ponownie pro- cedurę error, jednak rozpoczęliśmy już wyświetlanie nagłówka HTML-owego i takie działanie mogłoby wprowadzić w błąd serwer WWW). Jeśli nie ma żadnych dalszych problemów, w linii 813. kończymy program. 818 else { 819 print 820 821 822 FormHandler Alert: Missing Required Fields 823 824 f& a 825 FormHandler Alert: Missing Required Fields 826 The following fields were not filled in when you submitted your form, 827 but are required information. 828 829 830 831 $CONFIG{'error_fields'} 832 833 834 835 Please use the Back button on your browser to return and 836 complete the Form. 837 838 839 HTML_END 840 exit; 841 } 842 } Jeśli wzorzec komunikatu błędu nie został określony, w dalszej części korzystamy [ Pobierz całość w formacie PDF ] |