Soru geçmişi:
Sözcük dizimi analizi (lexical analysis) — Perl kodunun yorumlanmasının ilk aşamasıdır. Bu aşamada, kaynak metin "lexemler"e (değişkenler, anahtar kelimeler, operatörler, literal değerler vb.) ayrılır. Perl'in özelliği, dilin sözdiziminin çok esnek olmasıdır; birçok yapı varyasyonlara izin verir ve değişkenler operatörler ve tanımlayıcılarla iç içe geçebilir.
Sorun:
Perl'in sözcük dizimi ayrıştırmasındaki ana zorluk, ayrıştırmanın belirsizliği ve değişkenlerin/stringlerin doğrudan kodda kullanılması durumunda tehlikedir; bu özellikle eval gibi yapılarda ve değişkenleri dosya, yol, düzenli ifadeler gibi stringler içine eklerken geçerlidir. Perl "çift ayrıştırma" yapmaz: Eğer eval için bir string oluşturursanız, ayrıştırma sıfırdan başlar, bu beklenmedik hatalar ve güvenlik açıkları (DBI için SQL enjeksiyonları, hatalı sözdizimi vs.) doğurabilir.
Çözüm:
Sözcük dizimi ayrıştırmasında beklenmedik etkilerden kaçınmak için, mümkün olduğunca belirgin kod yazmak, kullanırken dikkatli olmak için use strict ve warnings kullanmak, gereksiz eval'den kaçınmak ve dinamikliği string eklemek yerine yapılandırarak ifade etmek (alt programlar, kapanışlar ve veri tiplerini güçlü bir şekilde belirleyerek) tercih edilmelidir. Karmaşık yerleştirmeler için genellikle sprintf, sprintf-benzeri formatlar ve örneğin, Text::Template gibi modüller kullanılır.
Kod örneği:
my $operation = 'print'; my $argument = 'Hello, world!'; # Asla Bunu Yapmayın: eval "$operation \"$argument\";"; # Tehlikeli! # Daha İyisi: if ($operation eq 'print') { print $argument; }
Anahtar özellikler:
Tuzak soru 1: "Eval kullanırken yalnızca tek ve çift tırnakları kaçırmak, güvenlik açıklarından kaçınmak için yeterli midir?"
Aslında, tırnakları basitçe kaçırmak, Perl ayrıştırıcısının dizeyi bir bütün olarak yorumlaması nedeniyle tüm olası güvenlik açıklarından korunmanızı sağlamaz ve karmaşık iç içe yapıların kaçırmayı aşabileceğini göz önünde bulundurmalısınız. Yapısal bir yaklaşım kullanın.
Tuzak soru 2: "Eval için güvenli Perl kodu oluşturmanın yolu olarak here-doc kullanılabilir mi?"
Here-doc, uzun stringlerin oluşturulmasını kolaylaştırır fakat yine de sözdizimi hatalarına karşı bir koruma sağlamaz ve temizlenmemiş verilerin yerleştirilmesi durumunda hala enjeksiyonlara maruz kalabilir. Bu güvenlik sağlamaz.
Tuzak soru 3: "Perl, doğrudan eval'a iletilmeyen stringlerde ifadeleri okur mu?"
Hayır, Perl yalnızca gerçekten yürütülebilir kodu ayrıştırır, eval veya benzeri mekanizmalar dışında stringler ayrıştırılmaz ve yürütülmez.
Bir programcı, kullanıcı parametrelerini doğrulamadan string içinde dinamik bir SQL sorgusu oluşturur ve ardından eval ile bu sorguyu yürütmeye çalışır.
Artılar:
Eksiler:
Dinamik eval yerine, DBI'de önceden hazırlanmış ifadeler kullanarak, parametreler yer tutucular aracılığıyla geçilir ve hatalar use strict ve warnings ile kapatılır.
Artılar:
Eksiler: