2011-09-06 34 views
2

in the CGI.pm docs報價:爲什麼CGI.pm仍然使用「 0」作爲空字符,當它被視爲Perl中的普通字符?

當使用這個,你必須注意的事情是多值CGI 參數。由於哈希無法區分標量和列表 上下文,因此多值參數將作爲由「\ 0」(空)字符分隔的打包字符串返回 。

然而,事實證明,\0沒什麼特別在Perl:

print length("test\0hi"); 

輸出是:

7 

,而在C中,它應該是4

爲什麼CGI.pm仍然使用\0作爲空字符,當它在Perl中被當作普通字符(而不是字符結尾的標記)?

+4

CGI.pm不使用它作爲空字符。它使用它作爲分隔符,因爲它不太可能在數據中。 –

回答

7

這是一個設計錯誤。我認爲我們同意它不應該將散列值強制轉換爲字符串,但當時它可能看起來是個好主意,並且由於各種重要性不重要的原因,它只是最不錯的選擇。

編輯:人們通常會避免把NULs放在他們的數據中,因爲它會在C程序中造成破壞,所以這使得這個角色更有利於分隔符。

編輯2hobbs comments,它可以追溯到的Perl 4,這樣的錯誤是不是在原來的設計,但在超過了承載它,然後不夠努力棄用的功能。

那麼,後見之明永遠是完美的。 Hash::MultiValue是您想到的更智能的數據結構。

+0

今天我讀了空字節故事! = P http://queue.acm.org/detail.cfm?id=2010365 – fvox

2

這是一個安全功能。

->Vars的用戶期望鍵值的散列,其中的值是字符串。如果其中一個值恰好是對數組的引用,那麼它會打破這種期望,並且可能會導致程序表現不佳。

如果要支持具有多個值的參數,請在列表上下文中使用->param。如果你願意的話,你可以用它來建立你自己的哈希。

my %hash; 
for ($cgi->params) { 
    $hash{$_} = [ $cgi->param($_) ]; 
} 

我強烈反對這是一個設計錯誤。我認爲這是處理錯誤數據的非常非常聰明的方式(參數的多個實例最多隻能有一個)。

+0

你是對的。這是一個安全設計,而不是一個設計_錯誤_。空(NULL)很少(如果有的話)是正確的數據,並且返回標量字符串是檢索數據的最安全的方法。 –

+2

「vars'的用戶希望鍵值的哈希值是字符串」,因爲他們的頭腦被CGI扭曲了。pm的粗製濫造的界面太多了,而CGI.pm的原因是這樣強調*不是*安全,而是因爲它是從perl4開始的api'cgi-lib.pl'的接口,其中引用不可用。不,「空值很少正確」不夠**。 '%00'是完全有效的輸入,百分比解碼發生在空連接之前。這種行爲更可能是安全漏洞的原因**而不是預防它們。 – hobbs

+0

@ hobbs,看起來'%00'沒有機會到CGI,因爲\形式中出現的所有\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'假設你需要輸入'\ 0'來產生'%00',但是'\ 0'會被轉換成'\\ 0' –

相關問題