3

たとえば、正規表現で\ wを使用すると、空白を含む500文字/桁でPCREが爆発する場合があります。bohTPerlRegExとDelphiXE2のpcre/objの実装を試しました。どちらも同じです。

それから私は電話してみました

pcre_config(PCRE_CONFIG_MATCH_LIMIT, @vSysStrRegex_MatchLimit_Value); 

ただし、一致制限を設定しても効果はないようです。私が使用している方法は、スレッドごとに1回呼び出すことです。(注:他の人は、このような設定を行わないようにこれを設定します)

スタックがオーバーフローするまで続行するのではなく、解析を中止するために正規表現ライブラリが本当に必要です。(そこからスレッド/プログラムを回復することはほぼ不可能のようです。)

この状況でスタックオーバーフローを防ぐにはどうすればよいですか?解析されるコンテンツや正規表現を制御できません。したがって、私は特に、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ドキュメントをいくつか引用しました。PCREライブラリを自分で作成する場合は、このオプションを実行できます。同じドキュメントの他の場所を読むと、渡されたブロックのフィールドの説明が見つかります。--with-match-limit-recursionmatch_limit_recursionpcre_extrapcre_exec

のデフォルト値はmatch_limit_recursion、PCREのビルド時に設定できます。デフォルトのデフォルトは、のデフォルトと同じ値ですmatch_limit。が設定され、 フィールドに 設定されpcre_exec() ている pcre_extra ブロックを 指定することにより、デフォルトをオーバーライドできます。制限を超えた場合は、を返します。match_limit_recursionPCRE_EXTRA_MATCH_LIMIT_RECURSIONflagspcre_exec()PCRE_ERROR_RECURSIONLIMIT

したがって、再帰制限をデフォルトよりも低い値に設定します。デフォルトは、実際に使用可能なスタックスペースよりも明らかに大きいです。それが低ければ、OSで発生したスタックオーバーフロー例外ではなく、すでにエラーが発生しているはずです。PCRE_ERROR_RECURSIONLIMIT

Delphi固有のラッパーがこの設定をどのように表すか、私にはわかりません。

于 2012-12-03T17:24:44.530 に答える