Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I spent a while looking at it last night and came up with a solution, I'll walk you through it. For reference, here's the code:

    function escape(s) {
      // Bonus level!

      Object.defineProperty(console, 'foo', 
         { get : function() { throw 'nooo!' } });

      var code = 'with(window.console && console.foo || {}) {\n\t'+s+'\n}';
      console.log(code);

      try {
        console.log(eval(code));
      } catch (e) {
        console.log(e);
      }
    }
The idea is, you need to craft `s`, such that `s` can execute arbitrary code without throwing 'nooo!'. The interesting problem is, any access to `console.foo` with throw because the getter above is called. This includes the access inside the `with` statement. So the solution, if there is any, must somehow cause mutation of state before the `with` even executes.

Now, what brought me to the solution was this thought: "What in Javascript allows you to execute code before a given statement?" Upon framing it in this way, the solution became immediately clear: function declarations are automatically hoisted!

If you redefine `console` to be an object without the property 'foo', the `|| {}` part of the with predicate will instead be passed as the scope, and you have free reign to walk about the system.

So the solution is:

    alert(1) } function console(){} {
Which produces the statement:

    with(window.console && console.foo || {}) { 
      alert(1) } function console(){} {
    }


Ah, cool. That's a little shorter than the solution that I came up with:

  function window(){alert(1)}window()
To those of you going for the code golf record, you can save a character in STRML's solution by redefining window instead. Furthermore, the last two braces can be omitted and whitespace removed for a total of 27 characters.


Ah, very clever, thanks :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: