Perfection kills

Exploring Javascript by example

Detecting global variable leaks

August 8th, 2009 by kangax (Permalink)

detect-global bookmarklet

I have recently stumbled upon a blog post by Remy Sharp on detecting global variable leaks. As you probably know, Javascript is notorious at making such leaks way too easy. The problem is mainly with undeclared assignments which result in global variable declarations when variables are not found in the scope chain.

  (function(){
    var x = 1; // <== accidentally changed "," to ";"
        y = 2; // <== `y` is now a global variable
  })();

To be more precise, undeclared assignment actually results in global property assignment, not global variable declaration. The difference between two is rather subtle: variable declaration creates non-deletable property of a global object, whereas explicit or implicit property assignment creates deletable one. Another peculiarity can be observed in IE, where global property assignment is disallowed if there’s an element in a document with the same-named ID or NAME value. Global variable declaration, on the other hand, quietly overwrites existing property in cases like this.

Remy solves the problem with a bookmarklet that creates a blank context (essentially a window in an empty iframe), then uses that clean context to get the difference with the main one. The list of found variables is dumped into a console.

It’s worth mentioning that JSLint already allows detecting undeclared assignments, but JSLint can hurt feelings so we won’t use it. Well, actually JSLint performs so many validations, that it’s not always possible to detect undeclared assignments in huge scripts of legacy applications (like the one I wanted to examine). Running a test such as in this bookmarklet can be “applied on” any script.

The bookmarklet worked like a charm, but as soon as I plugged it into one of our applications, I was greeted with dozens of Prototype and Scriptaculous -related methods. On top of those, there were few google analytics and Mozilla -specific ones. Unfortunately, the original code was obfuscated and almost unreadable so I reproduced it from the scratch, this time making it possible to toggle certain property sets on and off. These property sets are – Prototype, Scriptaculous, Mozilla, Google Analytics and Firebug ones. The code is structured in such way that it should be easy to augment it with additional sets.

In the end, I found few leaks in one of our applications and even one in firebug (now fixed).

As usual, the bookmarklet and its source are on github.

Feel free to fork it.

Edit [9/5/2009]

Clarified global variable declaration vs. global property assignment (thanks to Garrett Smith)

Categories: bookmarklet 18 Comments »

Comments (18)

  1. Gravatar

    Mats said:

    Did this a while back, http://mankz.com/code/globalcheck.htm, where you can analyze your own scripts etc.

    Also created a Selenium plugin for automating the leak detection.

    http://mankzblog.wordpress.com/2009/02/11/selenium-core-extension-for-finding-unexpected-global-variables/

  2. Gravatar

    kangax (article author) said:

    Mats,

    last time I looked at your FrameworkScanner, it wasn’t possible to examine non-public-url scripts (such as the ones in our intranet app or an app that’s in private testing). Even if I could have pasted script contents into your scanner, I might not be able to do so for confidentiality reasons. It must also be inconvenient to check each script individually, rather than click one button at any time after application has been initialized.

    Other than that, great job. I really liked framework analysis presented there.

  3. Gravatar

    Aaron said:

    This is great. Was just thinking about doing something like this a few days ago. Thanks!

  4. Gravatar

    @F1LT3R said:

    Ah nice! I suppose if you have written a long piece of code very quickly, or are starting work on someone else’s code for the first time, this would be an very useful little tool indeed. May give this a whirl on the code at my current contract and see how things look. Thanks!

  5. Gravatar

    T said:

    Ah, dumb question – how do you get a working ‘console’ to dump this to?

  6. Gravatar

    kangax (article author) said:

    Aaron, @F1LT3R, Thanks. I’m glad you found it useful.

    T, this script uses console.log and console.group for list dumping. console is usually present in Firefox (with Firebug installed and enabled) and Safari (with “developer tools” enabled). You can also define your own console if you wish and its log and group methods will automatically be used by the bookmarklet.

  7. Gravatar

    Predrag Stojadinovic said:

    Ahm, what is the bookmarklet supposed to do? I’m using FF 3.5 and when i click it it just shows me the JS code. I expected it to detecting global variable leaks and show me the result in the console?

  8. Gravatar

    kangax (article author) said:

    @Predrag
    I changed the link to include actual code. It was pointing to github’s source before.

  9. Gravatar

    Predrag Stojadinovic said:

    Awesome! THANKS! :)

  10. Gravatar

    Shuo Geng said:

    This is a pretty good idea to let yourself be aware if you pollute the global namespace. I have put it to my utility toolkit. Nice work!

  11. Gravatar

    Zach Leatherman said:

    Tried this on my stuff, and found a leak in jQuery! But looks like it’s already been reported and fixed for 1.3.3. Very useful!

  12. Gravatar

    kangax (article author) said:

    @Zach Leatherman

    Nice! Glad it helped :)

Trackbacks

  1. Readings | Prajwal Tuladhar's Blog said:

    [...] Detecting global variable leaks [...]

  2. Ajaxian » Detecting globals with a bookmarklet said:

    [...] stumbled upon a blog post by Remy Sharp on detecting global variable leaks. He took that work and updated it a little to filter out Prototype, Script.aculo.us, Google and Mozilla [...]

  3. Detecting global variable leaks in JavaScript [del.icio.us] [ False Positives ] said:

    [...] Detecting global variable leaks in JavaScript [del.icio.us] Found 14 minutes, 24 seconds ago From: thinkweb2.com [...]

  4. Detecting globals with a bookmarklet | Guilda Blog said:

    [...] stumbled upon a blog post by Remy Sharp on detecting global variable leaks. He took that work and updated it a little to filter out Prototype, Script.aculo.us, Google and Mozilla [...]

  5. Detecting globals with a bookmarklet - Programming Blog said:

    [...] stumbled upon a blog post by Remy Sharp on detecting global variable leaks. He took that work and updated it a little to filter out Prototype, Script.aculo.us, Google and Mozilla [...]

  6. The Ashes » Blog Archive » Detecting globals with a bookmarklet said:

    [...] stumbled upon a blog post by Remy Sharp on detecting global variable leaks. He took that work and updated it a little to filter out Prototype, Script.aculo.us, Google and Mozilla [...]

Leave a Comment

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Please, don't forget to escape your input (<, > and &). Wrap code sections with <pre>