3 ms·
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) {
by STRML 13y ago
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(){} {
}
- gibybo 13y agoAh, very clever, thanks :)
- pjob 13y agoAh, 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.