我找到了一个案例,例如在正则表达式中使用\ w时,500个字母/数字与空格会使PCRE爆炸。我试过boh TPerlRegEx
和Delphi XE2 pcre / obj实现。两者都相同。
然后我试着打电话
pcre_config(PCRE_CONFIG_MATCH_LIMIT, @vSysStrRegex_MatchLimit_Value);
但设置匹配限制似乎没有任何效果。我使用它的方式是我为每个线程调用一次。 (注意:其他人已将此设置为获取而非设置此类设置)
我真的需要正则表达式库退出解析而不是继续直到它溢出堆栈。 (似乎几乎不可能从中恢复线程/程序。)
在这种情况下如何防止堆栈溢出?我无法控制解析的内容或正则表达式。因此,我特别寻找避免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, ...)
答案 0 :(得分:3)
您引用some PCRE documentation描述了使用--with-match-limit-recursion
配置选项在编译时设置递归限制 。如果您自己构建PCRE库,则可以执行该选项。如果您在该文档的其他位置阅读,则会找到传递给match_limit_recursion
的{{1}}块的pcre_extra
字段的说明:
建立PCRE时可以设置
pcre_exec
的默认值;默认默认值与match_limit_recursion
的默认值相同。您可以通过在match_limit
块中添加pcre_exec()
,并在pcre_extra
字段中设置match_limit_recursion
来覆盖默认值。如果超出限制,PCRE_EXTRA_MATCH_LIMIT_RECURSION
将返回flags
。
因此,将递归限制设置为低于默认值的值。默认值显然甚至高于实际可用的堆栈空间;如果它更低,那么你已经得到pcre_exec()
错误,而不是操作系统引发的堆栈溢出异常。
特定于Delphi的包装器如何表示此设置,我不知道。