Javascriptで "2 *(3 + 4)"のようなユーザー入力の算術式を評価する必要がありますが、セキュリティ上の理由からeval
は使用しません。Javascriptで算術式を安全に評価する
cos
、
sqrt
、などのような機能を使うことができれば、それはいいだろうわからないすべての文字を取り除くことができ
...
算術式の評価を行うJavascriptライブラリはありますか?
Javascriptで "2 *(3 + 4)"のようなユーザー入力の算術式を評価する必要がありますが、セキュリティ上の理由からeval
は使用しません。Javascriptで算術式を安全に評価する
cos
、
sqrt
、などのような機能を使うことができれば、それはいいだろうわからないすべての文字を取り除くことができ
...
算術式の評価を行うJavascriptライブラリはありますか?
あなたはJavaScript Expression Evaluatorを試すことができます。
このライブラリは ラファエルグラーフのActionScript表現 パーサの修正版です。 JavaScript 関数プロッタを記述したとき、私はを の方が良く、JavaScriptのeval 関数の代わりに使用したいと思っていました。 セキュリティリスクはありません。 コードは自分のブラウザでのみ実行できますが、2^xの代わりにMath.pow(2^x) などの便利なコードは ではありません。
その後、あなたのコードがそのようになります:
console.info (Parser.evaluate("2 * (3 + 4)")); //prints 14
ありがとう!それはまさに私が探していたものです。私は私が "表現評価"の可能なバリエーションをすべて見つけようと誓っています... –
正規表現を使用して、ホワイトリスト以外のすべてを置き換えることができます。しかし、JavaScriptがクライアント上で実行されているので(あなたがAOL httpサーバーを実行している場合を除き)、入力を変更できる人なら誰でもコードを変更することができます。多かれ少なかれ安全ですすでにあります。
評価する式を入力するユーザーがこの式を評価するユーザーと同じかどうかによって異なります。 – Bruno
は、既に述べたように、すべてのユーザーが行うことができ、ほとんどの被害は、彼らはすでにのいずれかに内蔵されたコンソールを使用して何ができるかはかなりあります主要なブラウザしかし、ユーザがMath
のプロパティ/メソッドを使用するように制限したい場合は、これを処理する簡単な正規表現を書くことができます。このような何か作業をする必要があります:
function mathEval (exp) {
var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig,
valid = true;
// Detect valid JS identifier names and replace them
exp = exp.replace(reg, function ($0) {
// If the name is a direct member of Math, allow
if (Math.hasOwnProperty($0))
return "Math."+$0;
// Otherwise the expression is invalid
else
valid = false;
});
// Don't eval if our replace function flagged as invalid
if (!valid)
alert("Invalid arithmetic expression");
else
try { alert(eval(exp)); } catch (e) { alert("Invalid arithmetic expression"); };
}
私はあなたがセキュリティ上の理由からeval
を使いたくなかったが、それはの直接プロパティではありませんが、任意の単語を除外するとして正規表現は、それはかなり安全にする必要があります実現します代入演算子(=
)と2項演算子を含むMath
オブジェクトとほとんどの非算術JS演算子。より難しい方法は、正規表現ではないため、数式を解析するトークナイザを書くことです。
私が書いたのは、あなたが問題が発生した場合や、お気づきの点がございましたら、コメントを残しておいてください。私はそれを修正するために何ができるかを見ていきます。
Math.PI
のようなもののための下部ケースを許可すると便利かもしれません
in JavaScript chatを述べました。その場合は、あなただけの置換機能で、次の
else if
のステートメントを追加することができます。
else if (Math.hasOwnProperty($0.toUpperCase())
return "Math."+$0.toUpperCase();
をif
とelse
声明(example)の間に、それを追加します。
偉大なアプローチは、それは私に同様の問題を解決するのを助けた – odiseo
"どのような主要なブラウザでも組み込みのコンソールを使ってできることは、偽りの前提に基づいています。文字列は、サーバーとURLを介してブラウザの外部から取得されます。最善の方針は、関数への入力が、他の開発者がアプリケーションに追加するときに期待していない場所から来ると仮定してコード化することです。これは、 'eval'のような強力な演算子を使わないことを意味します。 –
@Mike:私は100%の意見に同意するのは難しいです。あなたが言ったことは他のソースからの入力を評価するときは真実ですが、私はあなたがユーザー入力を評価しているときの私の答えを立てています。 –
JavaScriptの評価を使用しないmath.jsの高度な式パーサーを使用できます。
使用法:
var ans = math.eval('2 * (3 + 4)');
または(変数と関数割り当てをサポートしている)パーサを使用します。
var parser = math.parser();
var ans = parser.eval('2 * (3 + 4)');
var result = nerdamer('sqrt(4)+cos(1)-2').evaluate();
document.getElementById('text').innerHTML = result.text();
<script src="http://nerdamer.com/js/nerdamer.core.js"></script>
<div id="text"></div>
あなたがロールしていない限り、セキュリティ上の問題は解決されませんか? – James