开发者

How to match & or ; or < or > or | in a regular expression?

The following regex works to confirm if the input passed into it contains the string 'ping'

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

Now I want to confirm if the input passed contains the pipe command |

The following does not seem to be working correctly:

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

For context I have the following if, elseif subroutine. I just added the 5 statements to the top of it that check for & or ; or < or > or |. But it's not working correctly... now it always goes to &PrintPageHeaderBC("c"); and attempts that contain ping, nslookup, etc (the acceptable commands) now do not do what they are supposed to do. I believe the problem must be that the 5 regexes I added are not correct for matching and text entered that contains & or ; or < or > or |. Any help? I'm sure the 5 individual statements that I did (probably incorrectly), could be combined into one statement as well.

# 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);
     开发者_JAVA百科               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;

}


The | symbol is used for alternation in regex. You need to escape it if you want to match a literal | character:

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

Additionally, if I was going to hazard a guess, I would say the reason it's always falling into the "failure" subroutine is because of that regex. With alternation (as written) it's matching any string that starts with with either \s* OR \s+(.+), which is literally any string due to the star operator in \s*.

Edit: Regarding your comment, those examples will not be matched by any of your regexes due to the anchoring (^). If we take for example the string ping 4.2.2.2; pwd, what happens is that the regex engine starts matching at the beginning of the string because it is anchored. The initial \s* matches correctly by repeating zero times, effectively doing nothing in this case. It then looks for a ; to match, but the next character is a 4, thus it fails. The same is true of the second string you provided. It would also break if there was no space after the ; since you used \s+.

Honestly, if you really do just want to prevent any string that even so much as contains the characters <, >, ;, | or &, the easiest thing to do would be to just stick them all into a character class and match against that, using m/[&;|<>]/g. Since this regex is unanchored, it will match at any point in the string. This would disallow these characters completely, though, meaning they could not appear in strings or anything of the sort. This may not be what you want, but it would apply to the rules as you've currently stated them ("The five regexes are supposed to match any text that contains & or ; or < or > or |").


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

needs to be:

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

| is the logical 'or' operator in regex, so you need to escape it if you're trying to match it


You need to escape special characters with a \. For example, to search for | escape it like this, \|. So your regex match becomes:

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

The following characters all have special meaning in regex and need to be escaped if you want them to be interpreted literally:

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


Use a "character class" and a single if.

The .* at the end doesn't do anything useful, so it should not be there.

Allowing "one or more" trailing spaces also does nothing useful, so it should be omitted as well:

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


You need to escape pipe character, just like eldarerathis said. You also may want to combine first 5 cases into character class:

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

That will save you a lot of space and time for future maintenance.

That [&;><\|] will match any of specified characters.

Read Bracketed Character Classes for more:


It helps if you use the /x modifier to space out your REs:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜