def test_obfuscate_no_global_recursive(self): node = es5( dedent(""" (function named(param1, param2) { param1 = param1 * param2 - param2; param2--; if (param2 < 0) { return named(param1, param2); } return param1; })(); """).strip()) self.assertEqual( dedent(""" (function named(b, a) { b = b * a - a; a--; if (a < 0) { return named(b, a); } return b; })(); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=False), ))(node)))
def test_obfuscate_try_catch_shadowed(self): node = es5( dedent(""" var value = 1; try { console.log(value); throw Error("welp"); } catch (value) { console.log(value); } """).strip()) self.assertEqual( dedent(""" var a = 1; try { console.log(a); throw Error("welp"); } catch (a) { console.log(a); } """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=True), ))(node)))
def test_functions_in_lists(self): node = es5( dedent(""" (function main(root) { root.exports = [ (function(module, exports) { module.exports = {}; }), (function(module, exports) { exports.fun = 1; }), ]; })(this); """).strip()) self.assertEqual( dedent(""" (function main(a) { a.exports = [(function(a, b) { a.exports = {}; }), (function(b, a) { a.fun = 1; })]; })(this); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(), ))(node)))
def test_obfuscate_try_catch_scope_inside_catch(self): node = es5( dedent(""" var value = 100; (function() { var dummy = 0; console.log(value); value = 1; try { console.log(value); throw Error("welp"); } catch (exc) { var value = 2; var welped = value; welped = 'welped'; (function() { console.log(exc); console.log(value); console.log(welped); })(); } value = 3; })(); console.log(value); """).strip()) # note that dummy -> c because exc is a local, not counted in # the priority at the parent scope. self.assertEqual( dedent(""" var value = 100; (function() { var c = 0; console.log(a); a = 1; try { console.log(a); throw Error("welp"); } catch (d) { var a = 2; var b = a; b = 'welped'; (function() { console.log(d); console.log(a); console.log(b); })(); } a = 3; })(); console.log(value); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(), ))(node)))
def test_obfuscate_globals(self): node = es5( dedent(""" var a_global = 1; (function(a_param) { var a_local = 1; a_local = a_param; a_local = a_global; })(); """).strip()) self.assertEqual( dedent(""" var a_global = 1; (function(b) { var a = 1; a = b; a = a_global; })(); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=False), ))(node))) self.assertEqual( dedent(""" var a = 1; (function(c) { var b = 1; b = c; b = a; })(); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=True), ))(node)))
def test_obfuscate_no_shadow_funcname_not_mapped(self): node = es5( dedent(""" function a(arg) { } """).strip()) self.assertEqual( dedent(""" function a(b) { } """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=False, shadow_funcname=False), ))(node)))
def test_multiple_reuse(self): tree = es5( dedent(""" (function() { var foo = 1; var bar = 2; bar = 3; })(this); """).strip()) obfuscator_unparser = Unparser(rules=( minimum_rules, obfuscate(), )) self.assertEqual( ''.join(c.text for c in obfuscator_unparser(tree)), ''.join(c.text for c in obfuscator_unparser(tree)), )
def test_obfuscate_try_catch_vardeclare_inside_catch(self): node = es5( dedent(""" var value = 100; (function() { console.log(value); value = 1; try { console.log(value); throw Error("welp"); } catch (exc) { var value = 2; console.log(value); } value = 3; })(); console.log(value); """).strip()) self.assertEqual( dedent(""" var value = 100; (function() { console.log(a); a = 1; try { console.log(a); throw Error("welp"); } catch (b) { var a = 2; console.log(a); } a = 3; })(); console.log(value); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(), ))(node)))
def test_no_shadow_children(self): node = es5( dedent(""" var some_value = 1; (function(param) { a.is_not_declared_in_this_file(param); })(); """).strip()) self.assertEqual( dedent(""" var b = 1; (function(b) { a.is_not_declared_in_this_file(b); })(); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=True), ))(node)))
def test_obfuscate_skip(self): node = es5( dedent(""" (function(a_param) { var a_local = a_param; })(); """).strip()) self.assertEqual( dedent(""" (function(c) { var d = c; })(); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(reserved_keywords=( 'a', 'b', )), ))(node)))
def test_obfuscate_try_catch_no_declare(self): node = es5( dedent(""" var value = 100; (function() { value = 1; try { console.log(value); throw Error("welp"); } catch (value) { value = 0; console.log(value); } console.log(value); })(); console.log(value); """).strip()) self.assertEqual( dedent(""" var value = 100; (function() { value = 1; try { console.log(value); throw Error("welp"); } catch (a) { a = 0; console.log(a); } console.log(value); })(); console.log(value); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(), ))(node)))
def test_no_shadow_parent_remapped(self): node = es5( dedent(""" var a = c; (function(param) { b.is_not_declared_in_this_file(a, param); })(c); """).strip()) # param can remap to c because the global 'c' not used in that # scope. self.assertEqual( dedent(""" var a = c; (function(c) { b.is_not_declared_in_this_file(a, c); })(c); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=True), ))(node)))
def test_obfuscate_no_global_recursive_redeclared_no_shadow_funcname(self): node = es5( dedent(""" (function $() { $(); (function $() { var foo = 1; })(); })(); """).strip()) self.assertEqual( dedent(""" (function $() { a(); (function a() { var b = 1; })(); })(); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(obfuscate_globals=False, shadow_funcname=False), ))(node)))
def test_multi_scope(self): node = es5( dedent(""" (function(value) { var parent = 1; (function(value) { var child = 2; (function(value) { var grandchild = 3; (function(value) { var greatgrandchild = 4; (function(value) { var result = 1; // using greatgrandchild a lot to ensure priority // mucking console.log(parent); console.log(greatgrandchild); console.log(greatgrandchild * value); console.log(greatgrandchild * parent); console.log(greatgrandchild * greatgrandchild); })(value); })(value); })(value); })(value); })(0); """).strip()) # Note that grandchild and greatgrandchild never had any of # their local variables referenced by any of their nested # scopes, their values got shadowed in the greatgrandchild scope # before both that and parent is used in the innermost scope. # Also, note that since greatgrandchild stopped propagating the # reference usage upwards, even though it has a lot more usage, # it never will claim priority over the parent at the parent # scope since parent got mapped to 'a' thus forcing # greatgrandchild to map to 'b', the next lowest value symbol. self.assertEqual( dedent(""" (function(b) { var a = 1; (function(b) { var c = 2; (function(b) { var c = 3; (function(c) { var b = 4; (function(c) { var d = 1; console.log(a); console.log(b); console.log(b * c); console.log(b * a); console.log(b * b); })(c); })(b); })(b); })(b); })(0); """).lstrip(), ''.join(c.text for c in Unparser(rules=( default_rules, indent(indent_str=' '), obfuscate(), ))(node)))