Checkstyle 4.4 RegExpチェックによるStackOverflowError
-
05-07-2019 - |
質問
こんにちは、
背景:
CheckStyle 4.4.2とRegExpチェッカーモジュールを使用して、出力Javaソースヘッダーのファイル名が存在するクラスまたはインターフェイスのファイル名と一致しないことを検出しています。これは、開発者が1つのクラスから別のクラスにヘッダーをコピーし、" File:"を変更しない場合に発生する可能性があります。タグ。
RexExpチェッカーでの正規表現の使用は、多くの化身を通じて行われており、(この時点ではおそらくやり過ぎかもしれませんが)次のようになります:
File: (\w+)\.java\n(?:.*\n)*?(?:[\w|\s]*?(?: class | interface )\1)
チェックしているファイルの基本形式は(非常に単純化されていますが)このようになります
/*
*
* Copyright 2009
* ...
* File: Bar.java
* ...
*/
package foo
...
import ..
...
/**
* ...
*/
public class Bar
{...}
問題:
一致するものが見つからないとき(つまり、" File:Bar.java"を含むヘッダーがファイルBat.javaにコピーされるとき)非常に長いファイルでStackOverflowErrorを受け取ります(私のテストケース@ 1300行です)。
視覚的な正規表現テスターをいくつか試してみましたが、 一致しない場合 では、正規表現エンジンがクラスまたはインターフェイス名を含む行を渡すと、次の行で再度検索を開始し、StackOverflowErrorを引き起こす可能性があるバックトラッキングを実行します
質問:
正規表現を変更してStackOverflowErrorを防ぐ方法
一致しないケース で正規表現を変更する方法はありますか(つまり、「File:Bar.java」を含むヘッダーがコピーされる場合)ファイルBat.javaに)インターフェースまたはクラス名を含む行を調べて" \ 1"最初のグループと一致しません。
代わりにそれが可能であれば、インターフェースまたはクラスを含む行を調べた後に行われる検索とマッチングを最小化し、処理と(できれば)StackOverflowエラーを最小化することは可能ですか?
解決
試用
File: (\w+)\.java\n.*^[\w \t]+(?:class|interface) \1
dot-matches-allモード。根拠:
[\ w \ s]
(|はそこに属していません)は、改行を含むすべてに一致します。これにより、正規表現の前の部分が一致した行に戻る多くのバックトラックが発生します。
貪欲なドットでファイルの最後まですべてをむさぼり(クイック)、単語またはスペース/タブで始まる行を見つけるまでバックトラックしますが(改行はありません)、 class
または interface
と\ 1の場合、スタックスペースはそれほど必要ありません。
別の、おそらくより良い解決策は、問題を部分に分割することです。
最初に File:(\ w +)\。java
部分に一致します。次に、 ^ [\ w \ t] +(?: class | interface)
と同じファイルでの最初の検索からの \ 1
の一致で2回目の検索を実行します。
他のヒント
フォローアップ:
上記のTim Pietzcherの提案をプラグインすると、彼の貪欲な解決策は実際に速く失敗し、一致するものが見つからなかった場合にStackOverflowErrorが発生しませんでした。ただし、正の場合、StackOverflowErrorが引き続き発生しました。
ソースコードを確認しました RegexpCheck.java 。クラスパターンは、式^および$がそれぞれ行末記号または入力シーケンスの終わりの直後または直前に一致するように、複数行モードで構築されます。次に、クラスファイル全体を文字列に読み取り、パターンを再帰的に検索します(findMatch()を参照)。これは間違いなくStackOverflowExceptionの原因です。
最終的には機能しませんでした(そしてあきらめました)Maven 2が約6週間前にmaven-checkstyle-plugin-2.4 / Checkstyle 5.0をリリースしてから、ツールをアップグレードすることにしました。これはStackOverflowErrorの問題を解決しないかもしれませんが、誰かがこれを再び追求する必要があると判断するまで、他に何か作業をすることができます。