簡體   English   中英

Javascript 中算術表達式的安全評估

[英]Safe evaluation of arithmetic expressions in Javascript

我需要在 Javascript 中評估用戶輸入的算術表達式,如“2 * (3 + 4)”,但出於安全原因我不想使用eval

我可以去掉所有不是數字或運算符的字符,但我不確定這是否安全,如果用戶可以使用cossqrt等函數會很好……

是否有任何 Javascript 庫可以進行算術表達式評估?

你可以試試JavaScript 表達式評估器

該庫是 Raphael Graf 的 ActionScript Expression Parser 的修改版本。 當我編寫 JavaScript 函數繪圖儀時,我想要一個更好的替代方法來使用 JavaScript 的 eval 函數 目前沒有安全風險,因為你只能在自己的瀏覽器中運行代碼,但它對數學不太方便(Math.pow(2^x) 而不是 2^x 等)。

那么你的代碼將是這樣的:

console.info ( Parser.evaluate( "2 * (3 + 4)" ) ); //prints 14

如前所述,任何用戶可能造成的最大損害幾乎是他們在任何主要瀏覽器中使用內置控制台已經可以做到的。 但是,如果您想限制用戶使用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 ,但正則表達式應該使它非常安全,因為它排除了任何不是Math對象和大多數非數學 JS 運算符的直接屬性的單詞,包括賦值運算符( = ) 和二元運算符。 更難的方法是編寫分詞器來解析數學表達式,因為它不是常規語言。

隨意嘗試打破我寫的工作示例,如果可以或如果您發現問題,請發表評論,我會看看我能做些什么來解決它。


注意:Yi Jiang [在 JavaScript 聊天中](https://chat.stackoverflow.com/rooms/17/javascript) 提到允許小寫字母“Math.PI”之類的東西也可能很有用。 如果是這種情況,您可以在替換函數中添加以下 `else if` 語句:
 else if (Math.hasOwnProperty($0.toUpperCase()) return "Math."+$0.toUpperCase();

ifelse語句之間添加它(示例)。

您可以使用 math.js 中的高級表達式解析器,它不使用 JavaScript 的 eval。

http://mathjs.org

用法:

var ans = math.evaluate('2 * (3 + 4)');

或使用解析器(支持變量和函數賦值):

var parser = math.parser();
var ans = parser.evaluate('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>

您可以使用正則表達式替換除白名單之外的所有內容。 但由於JavaScript是在客戶端上執行的(除非你正在運行的AOL http服務器)人誰可以修改輸入可以修改代碼,以及-所以你沒有真正做任何或多或少的安全比它已經是.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM