3

我发现了一个案例,例如在正则表达式中使用 \w 时,带有空格的 500 个字母/数字会使 PCRE 爆炸。我已经尝试过 bohTPerlRegEx和 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, ...)
4

1 回答 1

3

您引用了一些 PCRE 文档,这些文档描述了在编译时使用--with-match-limit-recursion配置选项设置递归限制。如果您自己构建 PCRE 库,则可以使用该选项。如果您在同一文档的其他地方阅读,您会发现传递给match_limit_recursion的块字段的描述:pcre_extrapcre_exec

match_limit_recursion构建PCRE时可以设置默认值;默认默认值与 的默认值相同match_limit。 您可以通过提供一个在其中设置和在 字段中设置pcre_exec()pcre_extra 块 来覆盖默认值。如果超出限制,则返回。match_limit_recursionPCRE_EXTRA_MATCH_LIMIT_RECURSIONflagspcre_exec()PCRE_ERROR_RECURSIONLIMIT

因此,将递归限制设置为低于默认值。默认值显然比您实际可用的堆栈空间还要高;如果它较低,那么您已经收到PCRE_ERROR_RECURSIONLIMIT错误而不是操作系统引发的堆栈溢出异常。

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

于 2012-12-03T17:24:44.530 回答