-1

次のようにフォーマットされた文字列があります。

function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3

持つ関数の数は無制限です (&& で分割されます)。

上記の文字列から生成される基本的な関数呼び出しは次のとおりです。

function1($param1,$param2);

そして2番目のもの:

function2($param1,$param2,$param3);

パラメータの数は無制限です。(単なる例であり、関数とパラメーターとは呼ばれません)

どんな質問にも喜んで答えます!! && で爆破してから !! しかし、動的パラメーターを使用して動的関数を呼び出す方法がわかりません。

5.2 のソリューション:

function function1( $a1, $a2 ) {
    echo $a1 . $a2;
}

function function2( $a1, $a2, $a3 ) {
    echo " ".$a1 . $a2 . $a3;
}
function explodemap($val) {
        $explode = explode( "!!", $val );
        return $explode[1];
}
$functions = explode( "&&", 'function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3' );

foreach( $functions as $function ) {
    $split = explode( "||", $function );
    $weird_excalmation_split = explode("!!", $split[0] );
    $params = array_slice( $split, 1 );

    $params = array_map( "explodemap", $params );

    $fn_name = $weird_excalmation_split[0];
    array_unshift( $params, $weird_excalmation_split[1]  );

    call_user_func_array( $fn_name, $params );
}
4

2 に答える 2

2

使用call_user_func_array

function function1( $a1, $a2 ) {
    echo $a1 . $a2;
}

function function2( $a1, $a2, $a3 ) {
    echo $a1 . $a2 . $a3;
}

$functions = explode( "&&", 'function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3' );

foreach( $functions as $function ) {
    $split = explode( "||", $function );
    $weird_excalmation_split = explode("!!", $split[0] );
    $params = array_slice( $split, 1 );

    $params = array_map( function($val) {
        return explode( "!!", $val )[1];
    }, $params );

    $fn_name = $weird_excalmation_split[0];
    array_unshift( $params, $weird_excalmation_split[1]  );

    call_user_func_array( $fn_name, $params );
}

//echoes param1param2param1param2param3
于 2012-08-19T12:24:43.210 に答える
1

上記のコメントで、使用eval()が潜在的なセキュリティ問題である理由を説明しました。

Androidアプリケーションからこのデータを受け取った場合、それはデータが安全ではなく、潜在的なハッカーによって簡単に変更される可能性があることを意味します。eval()受信した文字列を実行するために使用する場合 、関数名を変更することですべてのPHP関数を呼び出すことができます。たとえば、 function1文字列を変更するexec("rm -rf /"); function1と、オペレーティングシステムを含め、サーバー上のすべてのファイルが削除されます(exec()サーバーで有効になっていて、サーバーでUNIXが実行されている場合)。しかし、あなたはそれがどれほど危険であるかを見ることができるeval()ので、決してそれを使用しないでください!


しかし、call_user_func_array()安全ですか?

より安全ですが、それでも十分に安全ではありません。を使用eval()すると、文字列を実行するだけなので、関数名とパラメーターの両方を一度に指定できます。そして、それはでは不可能ですが call_user_func_array()、それでも指定された関数を実行します。つまり、私はまだ同じことを行うことができます。私があなたの文字列を exec!!rm -rf /あなたに変更したとしても、それでも問題があります。実際、唯一の良い方法は、すべての関数名をホワイトリストに登録された名前のリストと照合することです。


そして、どうすればこの操作を安全にすることができますか?switchステートメントまたはを使用して、許可されている関数を確認できますin_array()。以下の後者を使用した例:

<?php

// Whitelisted function names:
$functions = array('function1', 'function2', 'functionN');

// Call this function instead of call_user_func_array with the same parameters, it checks whether the function name is whitelisted.
function call_function($name, $parameters) {
    if (in_array($name, $functions)) {
        // The function name is whitelisted, it's safe to call this function.
        if (!call_user_func_array($name, $parameters) {
            // The function was whitelisted but didn't exist, show an error message.
        }
    } else {
        // A function was called that was not whitelisted! Write to log.
    }
}

?>

私はそれをテストしませんでしたが、これはうまくいくはずです。これがお役に立てば幸いです。

于 2012-08-19T16:32:55.857 に答える