Jak już wspomniano, najbardziej uszkodzić każdy użytkownik może zrobić jest dość dużo, co mogliby już nie za pomocą wbudowanego w konsolę którymś z główne przeglądarki. Jeśli jednak chcesz ograniczyć użytkownika do korzystania z właściwości/metod Math
, możesz napisać proste wyrażenie regularne, aby obsłużyć to za Ciebie. Coś jak to powinno działać:
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"); };
}
Zdaję sobie sprawę, że nie chcesz używać eval
ze względów bezpieczeństwa, ale regex powinien zrobić to całkiem bezpieczne, gdyż wyklucza jakiekolwiek słowa, które nie są bezpośrednie właściwości obiekt Math
i większość nie-matematycznych operatorów JS, w tym operator przypisania (=
) i operatory binarne. Trudniejszą metodą byłoby napisanie tokenizera, aby przeanalizować wyrażenie matematyczne, ponieważ nie jest to zwykły język.
Możesz spróbować złamać working example, napisałem, jeśli możesz, lub jeśli zauważysz problem, zostaw komentarz, a zobaczę, co mogę zrobić, aby to naprawić.
Uwaga: Yi Jiang wspomniano
in JavaScript chat, że może to być również przydatne w celu umożliwienia małych liter dla rzeczy jak
Math.PI
. Jeśli to przypadek, można po prostu dodać następujące
else if
oświadczenie w funkcji zastępczej:
else if (Math.hasOwnProperty($0.toUpperCase())
return "Math."+$0.toUpperCase();
Dodaj go między rachunku if
i else
(example).
Jeśli nie przeturlasz się samodzielnie, nie rozwiążesz żadnych problemów z bezpieczeństwem? – James