Regex /abcd^$/i与Perl中的任何内容匹配吗?

Regex /abcd^$/i与Perl中的任何内容匹配吗?,regex,perl,Regex,Perl,Perl是我从未完全有理由深入研究的东西之一。不幸的是,我有一个非常特定的Perl代码(对我来说像一个bug),我需要定义它的操作 此代码已编写并已投入生产,我希望将其删除 我相信这是不可能成功匹配的,但这是其中一件关于这个主题的猜测(尤其是我的)不够好的事情。它正在保护一个代码块{},不幸的是,它有多个条件,因此不管这个表达式的状态如何都可以输入,但是如果发生这种情况,就会出现安全问题(如果状态未定义,则本身就有一个bug,但是没有证据表明影响/严重性较低(读取永远不会得到修复)) 是否有可能

Perl是我从未完全有理由深入研究的东西之一。不幸的是,我有一个非常特定的Perl代码(对我来说像一个bug),我需要定义它的操作

此代码已编写并已投入生产,我希望将其删除

我相信这是不可能成功匹配的,但这是其中一件关于这个主题的猜测(尤其是我的)不够好的事情。它正在保护一个代码块
{}
,不幸的是,它有多个条件,因此不管这个表达式的状态如何都可以输入,但是如果发生这种情况,就会出现安全问题(如果状态未定义,则本身就有一个bug,但是没有证据表明影响/严重性较低(读取永远不会得到修复))


是否有可能成功地匹配?包括空字节插入或任何可能的字节/二进制数据?我甚至会进行一些疯狂的环境攻击(例如,在1字节内消耗主机上的所有内存,导致Perl表达式计算器在运行时未经检查的2字节分配失败)。创造力的荣誉。

来自perlre手册:

但是,您可能希望将字符串视为 多行缓冲区,这样“^”将在任何换行之后匹配 在字符串中(除非换行符是字符串中的最后一个字符) 字符串)和“$”将在任何换行符之前匹配。不惜代价 稍微增加一些开销,您可以通过在 模式匹配操作符。(较旧的程序通过设置$*来实现这一点,但是 这种做法在perl 5.9中已被删除。)

因此,请确保$*或其他预定义变量不会相互干扰

也就是说,即使是像/abcd^$/im这样的$*修改表达式(注意添加的“m”标志)也不会匹配任何内容,因为“^”字符仅在换行符之后匹配


另外,确保正则表达式没有过载。如果导入的包执行以下操作:

use overload;                                                                   
sub import {                                                                    
    overload::constant(qr => sub { $_ = shift; s/^abcd//; $_ });                 
} 
然后空字符串将匹配您的正则表达式


另外,不知道正则表达式在代码中是否是这样显示的,它可能不相关,但为了安全起见,不应该隐式匹配$\ux,而应该显式指定变量:“$str=~/abcd^$/i;”


$的作用域是动态的,因此如果您有任何函数调用可能会在定义它的位置和regexp的位置之间修改$,或者如果您稍后添加它们,您会感到惊讶:)

/abcd^$/i
/abcd^$/im
,如果
$*
设置为true(在5.9之前的Perl中)

我会重新写它
/abcd$^$/im

基本上,它是在一行末尾查找“
abcd
”,然后是一个空行


除了在“
^
”之前需要一些东西来捕获换行符。

正则表达式的目的是什么?也许它没有正确地完成工作,我们可以帮你解决。它试图匹配哪种类型的数据?是否有可能原始编码器试图匹配文字^?它会防范哪些情况

在这种情况下,我发现最好弄清楚代码中应该发生什么,而不是实际发生了什么。意图可能是正确的,但实现是错误的。错误确实会发生。:)


你可以考虑在它保护的代码中添加一个日志语句来查看它是否被触发。由于涉及到所有特殊变量和重载,您可能无法仅查看regex并了解它将做什么。如果你看到它被触发,你知道你仍然需要它。如果它从未被触发,那么,你仍然不知道。

顺便说一句,我想在这里指出
使用re'debug'
。您可以使用它来查看Perl是如何编译和匹配正则表达式的:

$ perl -Mre=debugcolor -e '/abcd^$/'
Compiling REx "abcd^$"
Final program:
   1: EXACT <abcd> (3)
   3: BOL (4)
   4: EOL (5)
   5: END (0)
anchored "abcd"$ at 0 (checking anchored) minlen 4
Freeing REx: "abcd^$"
$perl-Mre=debugcolor-e'/abcd^$/'
编译REx“abcd^$”
最终课程:
1:准确。

嵌入的换行符将不会与
^
$
匹配

文字
/abcd^$/
永远无法匹配,因为
^
仅在字符串开头或多行模式下的换行符之后匹配,因此模式末尾的
^$
需要帮助通过嵌入的换行符

对于较旧的perl,类似的模式可以匹配:

$ cat prog
#! /usr/local/bin/perl -w

$* = 1;
$_ = "AbC\n\n";
print /abc\n^$/i  ? "Match.\n" : "No match.\n";
print /abc\s*^$/i ? "Match.\n" : "No match.\n";

$ ./prog
Use of $* is deprecated at ./prog line 3.
Match.
Match.

请注意古老的perl-5.6.1中的弃用警告,这是可能的,但在病态方面。

我认为这应该是在stackoverflow上。您最好使用类似的工具进行测试,因为您可以更快地运行更多测试。尽管测试必须在真实脚本中进行验证。(即使不同的PERL版本也有差异,更不用说他尝试反向编码了)。@samgoody:我不想唠叨,但请用“PERL”来表示语言,用“PERL”来表示PERL解释器。malloc真的失败过吗?在linux上,您可以请求任意多的内存。如果你用得太多,你会被杀,或者其他什么东西会被杀。我添加了一个注释,这是我试图删除的现有代码。但是,按照这些思路,我确实尝试注射了一个\n到目前为止运气都不好的方法,让它允许我通过此检查。如果它使用较旧版本的解释器运行,则它仍然可能计算为true,除非您确定$*永远不会被修改。请注意,没有文字$*并不表示这一点,因为$str=“”${$str}=1;仍将修改$。我将把它发送给测试经理,看看我们是否可以摆脱某些限制并发布后续内容。无论是/abcd^$/m还是/abcd$^$/m都不会匹配以下任何一项:“abcd\n”、“abcd\n\n”、“abcd”、”。我能想出的最好的匹配方法是/abcd.^$/ms(“s”to make.”匹配新行)。“^”实际上只在换行后匹配。我假设
abcd
,只是代表实际的模式。哪种可能
$ perl -Mre=debugcolor -e '"not going to match" =~ /abcd^$/m'
Compiling REx "abcd^$"
Final program:
   1: EXACT <abcd> (3)
   3: MBOL (4)
   4: MEOL (5)
   5: END (0)
anchored "abcd"$ at 0 (checking anchored) minlen 4
Guessing start of match in sv for REx "abcd^$" against "not going to match"
Did not find anchored substr "abcd"$...
Match rejected by optimizer
Freeing REx: "abcd^$"
$ perl -Mre=debug -e '"abcd\nabcd\n\n" =~ /abcd^$/m'
...
anchored "abcd"$ at 0 (checking anchored) minlen 4
Guessing start of match in sv for REx "abcd^$" against "abcd%nabcd%n%n"
Found anchored substr "abcd"$ at offset 0...
Guessed: match at offset 0
Matching REx "abcd^$" against "abcd%nabcd%n%n"
   0 <> <abcd%nabcd>         |  1:EXACT <abcd>(3)
   4 <abcd> <%nabcd%n%n>     |  3:MBOL(4)
                                  failed...
   5 <abcd%n> <abcd%n%n>     |  1:EXACT <abcd>(3)
   9 <abcd%nabcd> <%n%n>     |  3:MBOL(4)
                                  failed...
Match failed
Freeing REx: "abcd^$"
$ cat prog
#! /usr/local/bin/perl -w

$* = 1;
$_ = "AbC\n\n";
print /abc\n^$/i  ? "Match.\n" : "No match.\n";
print /abc\s*^$/i ? "Match.\n" : "No match.\n";

$ ./prog
Use of $* is deprecated at ./prog line 3.
Match.
Match.