June 16, 2011

Why your Java math might be wrong

We all know that mathematical operations with decimals in JavaScript are no good. For instance:

alert(1.1 + 2.2); // should be 3.3, but the result is 3.3000000000000003

It turns out this is a cross to bare for pretty much any language that uses the IEEE-754 standard to implement a floating point number and that includes... *drums*... Java.

// Adding doubles
System.out.println(1.1 + 2.2); // 3.3000000000000003

// Adding floats
System.out.println(1.1f + 2.2f); // 3.3000002

So if you're doing these kinds of operations with float or double in Java you might be doing them wrong.

This is huge because an application that deals with money is almost certain to have to deal with decimals. You have to get it right or you'll be in a lot of trouble.

"People have a reasonable expectation that when you’re adding up their money you’re going to come up with the right result, and you don’t" - Douglas Crockford

float and double should never be used for currency or high precision operations.

The proper way to do this is using the BigDecimal class. Check out the documentation.

Let's try it again, this time using BigDecimal:

BigDecimal num1 = new BigDecimal(1.1);
BigDecimal num2 = new BigDecimal(2.2);
System.out.println(num1.add(num2)); // 3.30000000000000026645352591003756...etc.

Oh noes! what happened? I thought BigDecimal was supposed to solve all my problems.

Hold on, take another look at the code above. You'll notice we're constructing our BigDecimal objects using a... *drums*... double.

So? Well, that's the deal with float and double, it's why they should not be used in these operations. They cannot accurately represent numbers with decimals.

OK, how do we fix this? There's a constructor that takes a String argument (didn't you look at the documentation?). That's how we should always do it. Pass a String so you won't lose precision:

BigDecimal num3 = new BigDecimal("1.1");
BigDecimal num4 = new BigDecimal("2.2");
System.out.println(num3.add(num4)); // 3.3, finally

Perfect! now lawsuits won't be falling from the sky.

Thanks for reading and let me know your comments.

Sources:
Representing money
Beware of floating point numbers

May 26, 2011

How to hide your JavaScript code

Billy Hoffman, author of "Ajax Security", has a very interesting talk about JavaScript named "The Evil Parts" where he talks about the "evil" things a person can accomplish using JavaScript.

One of the things he shows us are two functions, a dehydrate and a hydrate function. He uses them to hide/display malicious code, to "dehydrate" JavaScript, so the code is transformed into whitespace and tabs, therefore becoming invisible.
// to "dehydrate" a string of code
function dehydrate(s) {
    var r = new Array();
    for (var i = 0; i < s.length; i++) {
        for (var j = 6; j >= 0; j--) {
            if (s.charCodeAt(i) & (Math.pow(2, j))) {
                r.push(' ');
            } else {
                r.push('\t');
            }
        }
    }
    r.push('\n');
    return r.join('');
}
// to "hydrate" a string of code
function hydrate(s) {
    var r = []; var curr = 0;
    while (s.charAt(curr) != '\n') {
        var tmp = 0;
        for (var i = 6; i >= 0; i--) {
            if (s.charAt(curr) == ' ') {
                tmp = tmp | (Math.pow(2, i));
            }
            curr++;
        }
        r.push(String.fromCharCode(tmp));
    }
    return r.join('');
}

So you dehydrate the code to hide it. And you hydrate it back and then eval it to execute it.
The code does become larger (x7 according to him) because it goes character by character transforming them, but hey, it's invisible code!

Give it a try, you know you want to.

Source:
Billy Hoffman - JavaScript: The Evil Parts

May 19, 2011

How many global variables are there?

We all know global variables in JavaScript are bad.

If you declare a bunch of variables/functions in the global namespace they become properties of the global object, in the browser that would be the window object.

So the other day I was thinking of a way to find out how many of them were in a page. So I came up with this script that you can run to find out:
(function (window) {
    var document = window.document,
        hasOwnProperty = Object.prototype.hasOwnProperty,
        globals = [],
        prop,
        div;

    for (prop in window) {
        globals.push('<li>');
        !hasOwnProperty.call(window, prop) && globals.push('@');
        globals.push(prop.toString());
        globals.push('</li>');
    }

    div = document.getElementById('abc-js-globals') ||
        document.createElement('div');
    div.id = div.id || 'abc-js-globals';
    div.innerHTML = '<h2>Global Variables:</h2><ul>'
        + globals.join('') + '</ul>';
    document.body.appendChild(div);

}(window));

You can paste that in the Firebug/Inspector console and a list of the globals will show up at the end of the page.
The names that start with @ mean they are properties inherited from the prototype chain.

UPDATE: I changed the code to be slightly faster (I think). I guess that makes it version 1.1.