2014-10-31 48 views
-1

我讀過有關Perl CGI,但我不明白open(HAIR,"hair".$q->param('Hair'));的Perl CGI開放機能的研究知識

#!/usr/bin/perl 

use CGI; 

$q = new CGI; 
if (defined($q->param('Head'))) { 
    print $q->header(-type => 'image/bmp'); 
    open(HEAD, "head" . $q->param('Head')); 
    open(HAIR, "hair" . $q->param('Hair')); 
    open(NOSE, "nose" . $q->param('Nose')); 
    open(MOUTH, "mouth" . $q->param('Mouth')); 
    open(EYES, "eyes" . $q->param('Eyes')); 

    while (read(HEAD, $headb, 1)) { 
     read(HAIR, $hairb, 1); 
     read(NOSE, $noseb, 1); 
     read(MOUTH, $mouthb, 1); 
     read(EYES, $eyesb, 1); 
     print(chr(ord($headb) & ord($hairb) & ord($noseb) & ord($mouthb) & ord($eyesb))); 
    } 
} 

我只看到開功能像open(FileHandle, filename),那麼什麼是.$q->param('Nose')

+0

CGI-> param()獲取發送到網頁的表單或查詢變量;例如http://example.com/?head=abc $ q-> param('head')將是'abc'。 – harvey 2014-10-31 06:09:54

+0

'print「hair」。$ q-> param('Hair');'也許?關於'open()'paractices => http://modernperlbooks.com/mt/2010/04/three-arg-open-migrating-to-modern-perl.html – 2014-10-31 06:42:10

回答

3

好的,讓我們看看這個邏輯。你知道open調用看起來是這樣的:

open(FileHandle, filename) 

而且你有一個開放的呼叫,看起來像這樣:

open(HEAD,"head".$q->param('Head')); 

參數之間用逗號隔開,所以這是很簡單解開這一點。 HEAD是文件句柄,"head".$q->param('Head')是文件名。

.這就是連接運算符。所以文件名將會是字符串「head」,然後是表達式$q->param('Head')的結果。 $q是你的CGI對象(從上面的$q = new CGI行創建,->是我們在Perl中調用對象方法的方法,你可以在CGI文檔中查找param方法,你會發現它提供了CGI參數的值因此$q->param('Head')爲您提供了一個字符串,其中包含CGI請求中包含的任何「Head」參數,並且您的文件名是字符串「head」後面跟着該值

值得指出的是,此代碼有一個列出一些最明顯的問題

  1. 所有的Perl代碼都應該包含use strictuse warnings。這意味着你需要聲明所有的變量(可能使用my)。
  2. $q = new CGI使用了一種過時且可能有問題的語法,稱爲「間接對象語法」。使用直接對象版本更好 - $q = CGI->new
  3. 你的文件句柄都是全局字符串(HEAD,HAIR等)。最好使用詞法變量來處理文件句柄 - open(my $head, "head".$q->param('Head'))
  4. 使用三參數版本open - open(my $head, '<', "head".$q->param('Head'))明確設置文件模式更安全。
  5. 您應該檢查從open返回的值,並採取適當的措施,如果它是錯誤的。
  6. 採取用戶輸入(如您的param調用)並直接在文件名中使用它是危險的。
+0

你能告訴我更多關於while(read( HEAD,$ headb,1)),那麼什麼是真實條件 – user3600331 2014-10-31 11:18:18

+0

如果你有一個單獨的問題,它可能值得開始一個全新的討論。但也許看看[閱讀文檔](http://perldoc.perl.org/functions/read.html)是否有幫助。 – 2014-10-31 11:44:12

+2

@ user3600331關於點3和5的註釋:如果沒有明確的開放模式,則該代碼非常容易受到殼體注入的影響,例如,用參數'; echo pwned |'(後面的管道讓Perl評估shell中的代碼)。而不是'echo',攻擊者會使用更具破壞性的東西,比如'rm -rf .' – amon 2014-10-31 16:09:40