2011-08-28 17 views
1

下面的正則表達式的工作,以確認是否傳遞給它的輸入包含字符串「平」如何匹配& or ;或< or >或|在正則表達式中?

elsif($RunCommand =~ m/^\s*ping\s+(.+)/) 

現在我想確認是否通過輸入包含管道命令|

下似乎並沒有被正確地工作:

elsif($RunCommand =~ m/^\s*|\s+(.+)/) 

對於方面,我有以下如果ELSEIF子程序。我只是將5條語句添加到頂部,以檢查&或;或<或>或|。但它不能正常工作...現在它總是去& PrintPageHeaderBC(「c」);並且包含ping,nslookup等(可接受的命令)的嘗試現在不做他們應該做的事情。我相信問題必須是我添加的5個正則表達式對於匹配和輸入的文本不正確,其中包含&或;或<或>或|。任何幫助?我確信我所做的5個單獨陳述(可能不正確),也可以合併爲一個陳述。

# First discard command attempts that contain & ; < > |, then acceptable commands are executed, then final else to non-functional command 

if($RunCommand =~ m/^\s*&\s+(.+)/) 
    { 
      # Print PageHeaderBC that informs of non-functional command 
      &PrintPageHeaderBC("c"); 

    } 

elsif($RunCommand =~ m/^\s*;\s+(.+)/) 
    { 
      # Print PageHeaderBC that informs of non-functional command 
      &PrintPageHeaderBC("c"); 

    } 

elsif($RunCommand =~ m/^\s*<\s+(.+)/) 
    { 
      # Print PageHeaderBC that informs of non-functional command 
      &PrintPageHeaderBC("c"); 

    } 

elsif($RunCommand =~ m/^\s*>\s+(.+)/) 
    { 
      # Print PageHeaderBC that informs of non-functional command 
      &PrintPageHeaderBC("c"); 

    } 

elsif($RunCommand =~ m/^\s*|\s+(.+)/) 
    { 
      # Print PageHeaderBC that informs of non-functional command 
      &PrintPageHeaderBC("c"); 

    } 

# Now start acceptable commands 

# PING 
elsif($RunCommand =~ m/^\s*ping\s+(.+)/) 
{ 
    &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 

} 
# TELNET 
elsif($RunCommand =~ m/^\s*telnet\s+(.+)/) 
{ 
    &PrintPageHeader("c"); 
    #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
    $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
    print "<code>$Prompt $RunCommand</code><xmp>"; 
    $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
    if(!$WinNT) 
    { 
     $SIG{'ALRM'} = \&CommandTimeout; 
     alarm($CommandTimeoutDuration); 
    } 
    if($ShowDynamicOutput) # show output as it is generated 
    { 
     $|=1; 
     $Command .= " |"; 
     open(CommandOutput, $Command); 
     while(<CommandOutput>) 
     { 
      $_ =~ s/(\n|\r\n)$//; 
      print "$_\n"; 
     } 
     $|=0; 
    } 
    else # show output after command completes 
    { 
     print `$Command`; 
    } 
    if(!$WinNT) 
    { 
     alarm(0); 
    } 
    print "</xmp>"; 
} 
#DIG 
elsif($RunCommand =~ m/^\s*dig\s+(.+)/) 
    { 
      &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 
    } 
#NSLOOKUP 
elsif($RunCommand =~ m/^\s*nslookup\s+(.+)/) 
    { 
      &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 
    } 

#HOST 
elsif($RunCommand =~ m/^\s*host\s+(.+)/) 
    { 
      &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 
    } 

#NMAP 
elsif($RunCommand =~ m/^\s*nmap\s+(.+)/) 
    { 
      &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 
    } 

#TRACEROUTE 
    elsif($RunCommand =~ m/^\s*traceroute\s+(.+)/) 
    { 
      &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 
    } 

#WHOIS 
    elsif($RunCommand =~ m/^\s*whois\s+(.+)/) 
    { 
      &PrintPageHeader("c"); 
      #$Prompt = $WinNT ? "$CurrentDir> " : "[admin\@$ServerName $CurrentDir]\$ "; 
      $Prompt = $WinNT ? "$CurrentDir> " : "\$ "; 
      print "<code>$Prompt $RunCommand</code><xmp>"; 
      $Command = "cd \"$CurrentDir\"".$CmdSep.$RunCommand.$Redirector; 
      if(!$WinNT) 
      { 
        $SIG{'ALRM'} = \&CommandTimeout; 
        alarm($CommandTimeoutDuration); 
      } 
      if($ShowDynamicOutput) # show output as it is generated 
      { 
        $|=1; 
        $Command .= " |"; 
        open(CommandOutput, $Command); 
        while(<CommandOutput>) 
        { 
          $_ =~ s/(\n|\r\n)$//; 
          print "$_\n"; 
        } 
        $|=0; 
      } 
      else # show output after command completes 
      { 
        print `$Command`; 
      } 
      if(!$WinNT) 
      { 
        alarm(0); 
      } 
      print "</xmp>"; 
    } 

else 
{ 
      # Print PageHeaderBC that informs of non-functional command 
    &PrintPageHeaderBC("c"); 

    } 
&PrintCommandLineInputForm; 
&PrintPageFooter; 

}

+0

調用子程序的標準方法是不** **領先符號:'PrintPageHeaderBC ( 「C」)'。 &符號調用樣式用於特定目的,詳見'perldoc perlsub'(http://perldoc.perl.org/perlsub.html)。 – FMc

+0

感謝您的信息......代碼實際上來自我已修改的cgi-telnet。我相信這是在2001年寫的:)不知道他是否有這樣做的原因,所以我只保留了他使用的相同格式。 – twain

+0

'cat/etc/password「|」' - 不包含管道命令,但我認爲它會通過正則表達式。 – Quentin

回答

2

你需要轉義特殊字符與\。例如,要搜索|就像這樣轉義,\|。所以,你的正則表達式匹配變爲:

m/^\s*\|\s+(.+)/ 

下面的字符都具有特殊含義的正則表達式,需要進行轉義如果你想讓他們從字面上解釋:

* ? + [ ] () { }^$ | \ 
6

|符號用於alternation在正則表達式。你需要逃避它,如果你想匹配一個|字符:

m/^\s*\|\s+(.+)/ 

此外,如果我要猜的話,我會說,它總是落入「失敗」子程序的原因是因爲那個正則表達式。通過替換(寫入),它匹配以\s*\s+(.+)開頭的任何字符串,這是字面上由於\s*中的星號運算符而產生的任何字符串。

編輯:關於你的評論,這些例子不會受到任何的正則表達式的因錨固(^)相匹配。如果我們以字符串ping 4.2.2.2; pwd爲例,會發生什麼情況是正則表達式引擎在字符串的開頭處開始匹配,因爲它是錨定的。最初的\s*通過重複零次正確匹配,在這種情況下實際上什麼都不做。然後它尋找一個;匹配,但下一個字符是4,因此它失敗。您提供的第二個字符串也是如此。因爲您使用了\s+,所以在;之後沒有空格時也會中斷。

老實說,如果你真的只是想阻止任何字符串,即使這麼多的包含字符<>;|&,最容易做的事情是隻堅持他們都爲一個字符類並與此相匹配,使用m/[&;|<>]/g。由於這個正則表達式是未錨定的,它將匹配字符串中的任何點。這將完全禁止這些字符,但是,這意味着它們不能以字符串或任何類型出現。這可能不是你想要的,但它適用於你現在聲明的規則(「五個正則表達式應該匹配任何包含&或;或<或>或|」的文本)。

+0

+ 1爲我打了幾秒鐘,也爲使用和鏈接術語'交替:) :) –

+0

感謝提示傢伙。在|上逃脫正則表達式的伎倆,但前5個正則表達式並沒有做我想讓他們做的事情。例如,如果有人輸入'ping 4.2.2.2; pwd'或者'ping 4.2.2.2 && pwd',那麼它應該進入失敗子程序,但它是執行命令。這五個正則表達式應該匹配任何包含& or ;或< or >或| (每個測試一個正則表達式),但它似乎允許包含這些字符的文本通過。 – twain

+0

@ user92272:錨定正在破壞這兩種情況(儘管如此,第二種情況還存在另一個問題)。我在回答中添加了一些內容,試圖解釋那裏正在發生的事情。 – eldarerathis

3
elsif($RunCommand =~ m/^\s*|\s+(.+)/) 

需求是:

elsif($RunCommand =~ m/^\s*\|\s+(.+)/) 

|是在正則表達式的邏輯「或」操作,所以你需要逃避它,如果你想與之相匹配的

0

您需要逃脫管道角色,就像eldarerathis說的。 您也可以先5案件合併成字符類:

if($RunCommand =~ m/^\s*[&;><\|]\s+(.+)/) { 
    PrintPageHeaderBC("c"); 
} 

,將節省您以後的維護有很大的空間和時間。

[&;><\|]將匹配任何指定的字符。

閱讀Bracketed Character Classes更多:

0

它幫助,如果您使用/ X修改太空,你的RE:

m/^ \s* \& \s+ (.+) /x 
1

使用「字符類」和一個如果。

*。最後沒有做任何有用的事情,所以它不應該在那裏。

允許「一個或多個」尾隨空格也沒有任何用處,所以 應該也省略:

if ($RunCommand =~ m/^\s*[&;<>|]\s/)