2

単純なパターンマッチングに取り組んでいます。以下はある意味で私が欲しいものを返します。それは私が望む方法ではありません。たとえば、結果は次のように出力されます。

一二三()

1

私が望むものではなく、 one();two();three()

の内破デリメータを無視する理由がわかりません。結果を返すとき。また、次の行に「one」という単語が含まれている理由もありません。リスト内の単語にのみ一致し、その単語が () を使用しているかどうかを確認するチェックが追加されている必要があります。したがって、「1」「2」「3」のような単語はそのままにしておきます。まだ 'one()' または 'one(somestuff)' に一致しています。

preg_match_all の区切り文字として # を使用しました。$str のエコーを改行して、この Web サイトでスクロールバーが作成されないようにしました。結果をフォーマットするためのエコーの使用は、最終コードには含まれません。コードがどのように返されるかを表示するためにそれらを使用していました。

これを修正する方法についてのヘルプは大歓迎です。私はおそらくコードが少しばかげています。

「編集2」について。それがより良い理解として役立つ場合。eval に渡される可能性のあるコマンドや関数をキャッチする方法を見つけようとしています。「関数 val1(val2)」または「val1(val2)」をスキャンする正規表現を設計しようとしています。また、「val1」と「(val2)」の間のスペースもマージされます。それが実際のコマンド/機能であるかどうかを判断するため。私が知っているように、'die("died")' または 'die ("died")' のようなことができます。空白の遭遇で2つの単語をマージしてから評価したかった. 自分でこれを理解しようとして、まだ遊んでいて、読んでいます。'Edit 2' もほとんどの単語に一致しますが、すべての単語をキャッチするわけではありません。また、式へのオプションの一致として ) を作成したくありません。IE は 'val1(val2)' と 'val1 (val2)' に一致します。チェックするものさえないかもしれないとき。次に、検出された場合に、ホワイトリストに対して潜在的なコマンドのみを実行します。そのようにして、ユーザーは「$you = "お元気ですか";」を提出しました 評価する権利を通過します。一方、「me($you)」はキャプチャされ、ホワイトリストに対して評価されます。チェックするものさえないかもしれないとき。次に、検出された場合に、ホワイトリストに対して潜在的なコマンドのみを実行します。そのようにして、ユーザーは「$you = "お元気ですか";」を提出しました 評価する権利を通過します。一方、「me($you)」はキャプチャされ、ホワイトリストに対して評価されます。

簡単に: 潜在的なコマンドをスキャンするには、つまり 'val1(val2)' をホワイトリストと照合してから評価します。システム コマンドのみがホワイトリストに登録されます。ユーザー コマンドは単に拒否されます。つまり、'preg_match_all' とユーザー作成の 'my​​func' です。

echo $str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
            echo \$you; \$t = \"one() two() three()\"; ";

if (preg_match_all('#(one|two|three)\(.*\)#i',$str,$m)){
    echo "\n---\n";
        foreach ($m as $k => $v){
            echo $k . "=" . implode(";",$v)."\n";
        }
    echo "---\n";
}

編集1:

$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you;
       echo \$us; echo \$you; \$t = \"one(two) two(1) three(2one)\"; ";

preg_match_all('#((one|two|three)\([\s\S]*?\))#i',$str,$m);
$t = implode(';',$m[1]);
if ($t != null))echo $t;
else echo "empty";

編集2:

$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
       echo \$you; \$t = \"eval($me)  one($two) two($1) three($2one)}meme1(you2) 
       this(that) die (\"meohmy\") function myfunc($me) empty() \"; ";

preg_match_all('#(([\w+]*)\([\s\S]*?\))#i',$str,$m);
    $t = implode(';',$m[1]);
        if ($t != null){
            echo $t;
            // check a whitelist for allowed commands vs ones captured here
        }else eval($str);

ミス:「死にます(「ミーオーミー」)」

マッチ: 'die($this)' と 'die($this'. 'die($this)' だけにマッチして 'die($this'.


編集3:

$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
       echo \$you; \$t = \"eval($me)  one($two) two($1) three($2one)}meme1(you2) 
       this(that) die (\"meohmy\") these function myfunc($me) empty()\"; ";

$cmd = preg_match_all('#(([\w+])*([\s\S])\([\s\S]*?\))#i',$str,$m);
$t = implode(';',$m[1]);
    if ($t != null){
        echo "Result : " . $t . " [" . $cmd . "]\n";
        // check a whitelist for allowed commands vs ones captured here
    }else eval($str);

一致: 不正な構造を持つ潜在的なコマンド。つまり、「this($one that($one)」は「this($one that($one)」を返します。「that($one)」のみを返し、「this($one」を除外するのではなく)。ホワイトリストにリストされていない一致を返すという点で、あまり重要ではありません.evalの実行は停止するだけです.


編集4:

含まれているコードについては、上記を参照してください。正規表現のみを提供します。

$cmd = preg_match_all('#(\w*)\s*\(.*?\)#i',$str,$m);

引き換えに、完全一致配列と単語配列のビットクリーナー。不正な形式の一致で停止する方法をまだ検討していますが。つまり、「func(val1)」に一致しますが、「func(val1」は除外します。これは正しいパターンではないためです。現在、正規表現は「func(val1 somefunc(val2)」に一致します。「)」にヒットしていないことだけに気付くためです。最初の一致で. したがって、一致するまでスキャンし、それをすべて一緒にメッシュします. 不正な形式を見て除外するのではなく.

考え: 私が読んでいたことの多くは、eval の前に関数の正規表現を介して文字列を解析することは効果がないことに気づいていました。そして、必要な関数は明示的に呼び出す必要があります。これらの同じ人々がfunction_existsを忘れている可能性があると思います。または、私の正規表現よりも優れた設計の正規表現です。function_exists に渡すデータを効果的に照合できます。願わくば、私の正規表現が現在のものよりも優れたものになるように間に合うようにしてください。だから、最終的な考えはです。関数の文字列を正規表現し、照合してから、function_exists を使用してスキャンします。その後、おそらくサニタイズして、それを評価します。

戻り値の例: eval($me) は、eval($me) と eval の 2 つの配列に出力されます。

私の編集は、私が積極的に助けを求めていることを示すはずです。私も自分でそれを理解しようとしていますが。ですから、私のためにできることだけではありません=)。自分でできるように理解しようとします。

入力:

eval($me) one($two) two($1) three($2one)}meme1(you2) this(that) die (\"meohmy\") function myfunc($me Holycrackers batman empty()

出力:

array (
  0 => 
  array (
    0 => 'eval($me)',
    1 => 'one($two)',
    2 => 'two($1)',
    3 => 'three($2one)',
    4 => 'meme1(you2)',
    5 => 'this(that)',
    6 => 'die   (\\"meohmy\\")',
    7 => 'myfunc($me holycrackers batman empty()',
  ),
  1 => 
  array (
    0 => 'eval',
    1 => 'one',
    2 => 'two',
    3 => 'three',
    4 => 'meme1',
    5 => 'this',
    6 => 'die',
    7 => 'myfunc',
  ),
)
4

1 に答える 1

1

あなたの質問が正しかったかどうかわかりませんが、それはあなたが期待したものでしたか?

<?php
$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
            echo \$you; \$t = \"one() two() three()\"; ";
$matches = array();
preg_match_all('/((one|two|three)\([\s\S]*?\))/i',$str,$matches);

echo implode(';',$matches[1]);
于 2013-03-25T09:15:25.683 に答える