1

For an online challenge, I've deobfuscated some code to this:

A = (0)['constructor']['constructor']

From what I've tried, this function takes some code as parameter and puts it in the body of an anonymous function and returns it.

A = (0)['constructor']['constructor']

console.log(A)
console.log(A('return 9'))
console.log(A('return 9')())

However, I don't understand this syntax and how the function is created. What's happening behind the scene ?

Mickael B.
  • 4,755
  • 4
  • 24
  • 48

1 Answers1

3

There's a surprising amount going on here, so I'll try to break it down into steps.

  • 0 is a primitive number. Primitives have no properties, and any attempt to retrieve a property (such as (0).constructor) will cause Javascript to automatically convert it to an Object representation. E.g. (0) becomes Number(0).
  • (0) is still a primitive, just with the addition of the grouping operators (). This is done here because, without the parentheses, the . in 0. is interpreted as a decimal point rather than a property accessor. You could achieve the same thing with 0..constructor or a number of other ways.
  • All Javascript objects have a prototype. You can see an object's prototype using its __proto__ property, e.g. (0).__proto__. The prototype is interesting because, when you try to access a property on the object, Javascript will also check the __proto__ object to see if that property exists on it. (This is used mainly for inheritance).
  • One of the properties on __proto__ is constructor. The constructor is a function that is called when the object is first created.
  • constructor is of type Function, which is itself an object with its own constructor property.

So, (0).constructor.constructor is shorthand for Number(0).__proto__.constructor.__proto__.constructor.

Your anonymous functions that return 9 do what they do because the constructor of a Function accepts as an argument a string representation of some Javascript code. It's equivalent to doing this:

Function('return 9')();

Edit: corrected a mistake regarding autoboxing and (0)

Benjamin
  • 1,372
  • 2
  • 12
  • 20
  • 4
    "*This is useful because the syntax causes it to automatically convert the primitive 0 to an object*" - no, it does not. All the grouping parenthesis do is to *syntactically* allow the property access. [See here](https://stackoverflow.com/q/9380077/1048572) for details. – Bergi Feb 05 '20 at 22:59
  • 3
    The "auto-boxing" happens when the property is accessed. A plain `const x = (0);` keeps a primitive number. – Bergi Feb 05 '20 at 23:01
  • `0..toString` is valid syntax and accesses that property. The `()` have nothing to do with the internal conversion to an object. – Felix Kling Feb 05 '20 at 23:27