Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi PCRE/regex实现和堆栈溢出_Regex_Delphi_Stack Overflow_Pcre - Fatal编程技术网

Delphi PCRE/regex实现和堆栈溢出

Delphi PCRE/regex实现和堆栈溢出,regex,delphi,stack-overflow,pcre,Regex,Delphi,Stack Overflow,Pcre,我发现一种情况,例如,在正则表达式中使用\w时,带空格的500个字母/数字会导致PCRE爆炸。我尝试过bohTPerlRegEx和Delphi XE2 pcre/obj实现。两者都一样 然后我试着打电话 pcre_config(PCRE_CONFIG_MATCH_LIMIT, @vSysStrRegex_MatchLimit_Value); 但设定比赛限制似乎没有任何效果。我使用它的方式是为每个线程调用一次。(注意:其他人已将此设置为get而未设置此类设置) 我真的需要正则表达式库退出解析,

我发现一种情况,例如,在正则表达式中使用\w时,带空格的500个字母/数字会导致PCRE爆炸。我尝试过boh
TPerlRegEx
和Delphi XE2 pcre/obj实现。两者都一样

然后我试着打电话

pcre_config(PCRE_CONFIG_MATCH_LIMIT, @vSysStrRegex_MatchLimit_Value); 
但设定比赛限制似乎没有任何效果。我使用它的方式是为每个线程调用一次。(注意:其他人已将此设置为get而未设置此类设置)

我真的需要正则表达式库退出解析,而不是继续解析,直到它溢出堆栈。(从中恢复线程/程序几乎是不可能的。)

在这种情况下,如何防止堆栈溢出?我无法控制解析的内容或正则表达式。因此,我特别寻找通过设置或类似设置避免PCRE运行到堆栈溢出的方法

通过编辑TPerlRegEx代码解决方案:

function TPerlRegEx.Match(AStartOffset: Integer = 0): Boolean;
...
if FHints <> nil then // set by "study" call
  begin
    PPCREExtra(FHints)^.flags := PPCREExtra(FHints)^.flags or PCRE_EXTRA_MATCH_LIMIT_RECURSION;
    PPCREExtra(FHints)^.match_limit_recursion := 750 // 1000 too much in tests
  end
;
OffsetCount := pcre_exec(FPattern, FHints, ...)
函数TPerlRegEx.Match(AStartOffset:Integer=0):布尔值;
...
如果FHints nil,则//由“研究”调用设置
开始
PPCREExtra(FHints)^.标志:=PPCREExtra(FHints)^.标志或PCRE_额外_匹配_限制_递归;
PPCREExtra(FHints)^.匹配\u限制\u递归:=750//1000在测试中太多
结束
;
OffsetCount:=pcre\U exec(FPattern、FHints等)
您所引用的描述了如何在编译时使用
--with match limit recursion
配置选项设置递归限制。如果您自己构建PCRE库,则可以使用该选项。如果您阅读同一文档的其他地方,您会发现传递到
pcre\u exec的
pcre\u extra
块的
match\u limit\u递归
字段的描述:

构建PCRE时,可以设置
匹配\u限制\u递归的默认值
;默认值与
匹配限制的默认值相同。您可以通过使用
pcre\u extra
块提供
pcre\u exec()
来覆盖默认值,其中设置了
match\u limit\u recursion
,并且在
标志
字段中设置了
pcre\u extra\u match\u recursion
。如果超出限制,
pcre\u exec()
返回
pcre\u ERROR\u RECURSIONLIMIT

因此,将递归限制设置为低于默认值的值。默认值明显高于实际可用堆栈空间;如果它更低,那么您已经得到了
PCRE\u ERROR\u RECURSIONLIMIT
错误,而不是OS引发的堆栈溢出异常


我不知道Delphi特定的包装器如何表示此设置。

我在问是否有人有此问题的解决方案和/或为什么似乎忽略了pcre_配置?由于没有可复制的测试用例,根据,
pcre\u config
用于读取特定pcre库在编译时是如何配置的。它告诉您库支持哪些功能以及支持的程度。因此,设置限制当然不起作用。我必须承认我是PCRE新手:我刚刚看到/限制了PCRE资源的使用:但是,您可以通过在configure命令中添加,例如,-with match limit recursion=10000来设置下限。此值也可以在运行时被覆盖,因为它是来自he帮助的引用。我认为pcre_config必须是在运行时进行更改的调用。显然,我一定是错了,但我试着用谷歌来回几个小时的例子来改变匹配限制运行时。我想我失败了。如何在运行时更改它?文档中说它在运行时会被过度覆盖。您没有误解“运行时”的含义。您只是没有阅读文档的相关部分。为了找到相关的部分,我在文档中搜索了“递归”,直到找到了一些关于在运行时设置它的内容。感谢您的帮助。我尝试了Google和搜索PCRE.pas Delphi源代码,但肯定没有找到您的解决方案。我将测试它并报告回来!(并接受答案。现在就投票表决。)它有效。我将match_limit_递归设置为750,因为1000太多了。(现在,我知道我也可以增加he线程的堆栈大小,但是,好吧,我更喜欢这个解决方案!)我已经接受了你的回答:)@Tom,作为将来的参考-也许你可以将最终的解决方案添加到你的问题中,你到底是如何在运行时覆盖设置的。@Arioch不,那是添加它的错误位置。在答案中添加答案。@David-但这不是他的答案,他也不会抢先一步。或者你的意思是添加他自己的解决方案,但不批准它?然后很多读者就会绕过它。