Skip to content

Instantly share code, notes, and snippets.

@maettig
Forked from 140bytes/LICENSE.txt
Created January 16, 2012 16:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maettig/1621774 to your computer and use it in GitHub Desktop.
Save maettig/1621774 to your computer and use it in GitHub Desktop.
dumpGlobalLeaks in 140byt.es

Clean JavaScript code does not leak into the global variable scope. That's why we use strange looking stuff like (function() { var a = 'I am local'; })(); to execute code in a local scope. Inside such scopes, we can declare and use variables without conflict.

Since you often don't get a warning when using undeclared variables, I wrote an 140byt.es snippet to detect leaking variables. The idea is very simple and works in Opera and Firefox. Does not work in Internet Explorer.

Due to a bug in Firefox I had to add a try-catch block. Accessing or even checking the type of window.sessionStorage causes a "not supported" exception. It works fine without this in all other browsers. Another bug is that Firefox returns a getInterface method in the second call that was not there in the first call. I did not found out why this happens or how to prevent it. This is why I check for native functions. And (of course) there are problems in Internet Explorer. It does not store global variables in the window object so the function can't display anything. Replacing window with this does not help since it refers to the same object.

Click here to run the test script.

function(a, b, c, d) //`window` (or something else) and three dummy arguments
{
d = a[b = 'Leak:' //collect all info in string `b`
] = a[b] || { }; //initialize the list of known properties, use `Leak:` as name
for (c in a) //check everything in the `window` object
try //not required in Opera, but Firefox crashs for `sessionStorage`
{
d[c] || //if this property is known from the previous call or
/\[native code]/.exec(a[c]) //if this is a native function
? 1 //then do nothing
: b += '\n' + c + ' = ' + a[c], //else add name and value to the string
d[c] = 1 //add this property to the list of known properties
}
catch (e) { }
return b //return the string
}
function(a,b,c,d){d=a[b='Leak:']=a[b]||{};for(c in a)try{d[c]||/\[native code]/.exec(a[c])?1:b+='\n'+c+' = '+a[c],d[c]=1}catch(e){}return b}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2012 Thiemo Mättig <http://maettig.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "dumpGlobalLeaks",
"description": "Debugging helper dumps all variables that leaked into the global scope.",
"keywords": [
"debugging",
"global",
"scope",
"test",
"variables",
]
}
<!DOCTYPE html>
<script type="text/javascript">
// 140 bytes
var dumpGlobalLeaks = function(a, b, c, d) //`window` (or something else) and three dummy arguments
{
d = a[b = 'Leak:' //collect all info in string `b`
] = a[b] || { }; //initialize the list of known properties, use `Leak:` as name
for (c in a) //check everything in the `window` object
try //not required in Opera, but Firefox crashs for `sessionStorage`
{
d[c] || //if this property is known from the previous call or
/\[native code]/.exec(a[c]) //if this is a native function
? 1 //then do nothing
: b += '\n' + c + ' = ' + a[c], //else add name and value to the string
d[c] = 1 //add this property to the list of known properties
}
catch (e) { }
return b //return the string
}
var goodFunction = function(a) //`a` is an unused argument, it's declared but not initialized
{
a = 1; //initialize `a`
var b; //declare `b`
b = 2; //initialize `b`
var c = 3; //declare and initialize `c` in a single statement
}
var badFunction = function()
{
a = 1; //leaks to the global scope since it's undeclared in the function
}
dumpGlobalLeaks(window); //first call returns everything, this should be ignored
goodFunction(); //call the non-leaking function
alert(dumpGlobalLeaks(window)); //should display an empty leak dump
badFunction(); //call the leaking function
alert(dumpGlobalLeaks(window)); //should display a leak dump with `number a = 1`
</script>
@maettig
Copy link
Author

maettig commented Feb 2, 2012

I did an update and re-added the "Leak:" message. Now it's exactly 140 bytes. Unintentionally, this also avoids the empty property name. Good to know, anyway. Thanks a lot for the research.

IE6 and IE10 didn't show up in my tests suite. Did IE6 countdown succeded? ;-) Update: It's true, setting window[''] works in IE5.5, IE6 and even in certain versions of IE7 but stopped working in IE8. In IE7, it depends on the operating system. It works in Windows Vista but does not in Windows 7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment