3

重複の可能性:
Javascript での算術式の安全な評価

私が取り組んでいるウェブサイトの一部として、オンライン計算機を構築しようとしています。

私は+ - * / ( ) AVG MIN MAX sine cos etc操作として持っています。数字、演算子、関数のボタンがあります。どんなボタンが押されても文字列を追加するだけです。

UI 側で基本的な構文チェッカーを作成する必要があります。サーバーは実際に操作を実行し、それらを保存して表示します。クライアント側のコードを書くのにあまり時間をかけたくありませんが、数学的に意味があることを確認するために検証することが目的です。

これが私の計画です:

生成された文字列を試してeval()、エラーをキャッチします。エラーが synatxError の場合、文字列が構文的に間違っていることを意味します。他のタイプのエラーであれば、問題ありません。

だから私はスクリプトの冒頭でこれをしました:

Error.prototype.dummy_attribute = "notSyntaxError"
SyntaxError.prototype.dummy_attribute = "SyntaxError"

2()文字列リンクがあると型エラーが発生するため、上記の方法はうまく機能しません。ここで、空の括弧と括弧の前に演算子がないか、または括弧の後に演算子がないかをチェックするコードを作成する必要があります

または、数学的に意味があるかどうかを確認する必要がある文字列の構文をチェックするために使用できる代替方法はありますか。

4

1 に答える 1

1

evalで可能です。私は何人かの熱心な評価嫌い者がこれに反対票を投じることを知っています. これが悪い唯一の方法は、クエリ文字列に方程式を使用してページへのリンクを提供できるようにすることです。これにより、XSS 攻撃を受ける可能性があります。検証のために現在のページでのみ使用すると、その人は自分のページを台無しにするだけで、他の人にリスクはありません。

基本的な考え方:

function avg () {
    var len = arguments.length;
    if(len===0) {
        throw "no arguments suppulied for AVG";   
    }
    var arr = Array.prototype.slice.call(arguments, 0);   
    var total = 0;
    for (var i=0; i<len; i++) {
        total += arr[i];
    }
    return total/len;
}
function sine (num) {
    return Math.sin(num);
}

function max () {

    var len = arguments.length;
    if(len===0) {
        throw "no arguments suppulied for MAX";      
    }   
    var arr = Array.prototype.slice.call(arguments, 0);
    return Math.max.apply(null, arr);

}


function isValidEqn (eqn) {
    try{
        eval("var x = " + eqn.toLowerCase());
        return !isNaN(x);
    } catch(e) {
        //console.error(e);
        return false;
    }
}



var eqn1 = "AVG ( 2008 , 2000 )";
var eqn2 = "AVG ( 2008 , 2000 ) / 100 + sine(10)";
var eqn3 = "AVG ( 2008 , 2000 ) / 100 + sine(10) + MAX(10,20)";

console.log("sadjhsahd", isValidEqn("sadjhsahd") );
console.log(eqn1, isValidEqn(eqn1) );
console.log(eqn2, isValidEqn(eqn2) );
console.log(eqn3, isValidEqn(eqn3) );
于 2012-10-18T13:44:53.217 に答える