1

I have a URL, that I am parsing after the hash. The content after the hash is a math equation (eg. http://example.com/something#5+1) which I would like to find the sum of (or the result of any other equation like a product, division, etc)

I can retrieve the numbers using:

var url = (window.location.hash).substr(1) // returns "5+1" as a string

Although I find if I try to convert this to a number it doesn't actually do the math. It cuts it down to 5, instead of showing the sum of 8.

Is this kind of conversion possible?

thanks!

Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
gleddy
  • 425
  • 1
  • 5
  • 13

6 Answers6

6

Do not eval() arbitrary code from the URL as it can easily be exploited for XSS. I have created a library called JSandbox that can sandbox JavaScript code execution, but it requires support for web workers. It would not be a good idea to use fake worker support for IE as then the safety of the sandbox is gone.

Your code would go as follows:

JSandbox.eval("with(Math){" + location.hash.substr(1) + "}", function (res) {
  // handle the results here
});

Use this to also handle errors:

JSandbox.eval("with(Math){" + location.hash.substr(1) + "}", function (res) {
  // handle the results here
}, null, function (err) {
  // handle errors here
});

I included a with (Math) { ... } wrapper so the hash code has short access to Math functions. (eg. abs(..) instead of Math.abs(..))

Eli Grey
  • 35,104
  • 14
  • 75
  • 93
1

eval() is the easiest way to perform the calculation, but you'll definitely want to verify that your input is sane:

var input = window.location.hash.substr(1);
var result = null;

try {
  // Make sure the input is only numbers and supported operators.
  if (/^[-+*/.()0-9]+$/.test(input))
    result = eval(input);
} catch (ex) {
  // Insert error handling here...
}

This regex should filter out any dangerous input.

Annabelle
  • 10,596
  • 5
  • 27
  • 26
1

To really do this correctly, you need to write a simple parser for your mathematical expression language. This is allegedly not very hard, but I myself have never been able to do it. This is the only way to get the javascript to evaluate and interpret the math expression correctly, without also opening pandoras box, and letting all kinds of nasty stuff through like a simple (and stupid) call to eval() will.

Or you can just have a bit of a look around and find someone who has already done this such as here:

http://silentmatt.com/math/evaluator.php

Breton
  • 15,401
  • 3
  • 59
  • 76
0

To execute a string see eval and some reasons not to do this are at why-is-using-javascript-eval-function-a-bad-idea.

This means in code of any importance—with data that is coming from an untrusted source (e.g. the internet)—you should parse out the numbers and the mathematical operation...and not accept any other types of input.

Community
  • 1
  • 1
0
var code = "5+1";
var result = window.eval(code);

But as in all languages that has eval, be careful with what you eval.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • 4
    If you use eval, precede it with a test, such as a regular expression, to ensure that the string to be eval'ed is what you're expecting. – jdigital Dec 24 '09 at 03:59
0
function CalculateString(hash) {
    var ReturnValue;

    var patt = '([\d*+-/.%])';
    ReturnValue = hash.match(patt)[1];
    ReturnValue = eval(ReturnValue);

    if (ReturnValue > 0) {
        return parseInt(ReturnValue,10);
    } else {
        return 0;
    }
}

So you can do like this:

var Hash = (window.location.hash).substr(1);
var Calculation = CalculateString(Hash); // Retinerer result of the calculation if it is valid, otherwise it will give you 0.
eriksv88
  • 3,482
  • 3
  • 31
  • 50
  • 1
    When calling `parseInt` you should include the radix - `parseInt(val, 10)`, or things might go octal... – Kobi Dec 24 '09 at 05:25
  • I know that Firebug gives error on it, but I have not yet found any documentation from the W3C, although that is requested. The closest I've found is this description here: http://www.w3schools.com/jsref/jsref_parseInt.asp. But I can update my answer:) – eriksv88 Dec 24 '09 at 05:37