简体   繁体   中英

Why does [eval] work in [eval][0]('code')?

I saw this way to execute the code:

[eval][0]('alert("hello")')  

I want to know what does unquoted 'eval' surrounded by square brackets mean and why this works. (For example, window['eval'][0]('alert("hello")') will lead to a TypeError). Is there any tutorials that describe such a syntax?

That is an indirect eval call

Quoting from the article:

According to ES5, all of these are indirect calls and should execute code in global scope .

So you can use these kind of "tricks" to execute eval in the global scope instead of the current one.

It works before [eval] is an array where its 0-th element is the eval function, that is, [eval][0] === eval , and you are invoking it passing the string 'alert("hello")' as the argument.

Unquoted eval surrounded by brackets is an Array with one element which is eval .

[eval][0]('alert("hello")')

means take the first element of the Array [eval] and pass 'alert("hello")' to it. In other words,

eval('alert("hello")')


window['eval'][0]('alert("hello")')

on the otherhand tries to get the first element of window['eval'] which is not an Array, and thus the TypeError. window['eval'] is the same as eval unless there is another variable in scope called eval .

The reason your example leads to a TypeError:

window['eval'][0]('alert("hello")')

is because you left out one set of brackets that would have made it equivalent:

[window['eval']][0]('alert("hello")')

The initial syntax you gave constructs an array with one element, the function eval. The 0th element of this array is therefore the eval function, which is immediately dereferenced using the square brackets.

In Javascript

[x]

is a list of one element containing x . thus

[x][0]

is just a wordy and inefficient way of saying x .

Your example

[eval][0]('alert("hello")')

is therefore just like

eval('alert("hello")')

This kind of trickery is normally found in Javascript trojan or viruses, where the author tries to disguise what is happening.

Javascript however is full of special cases and when used with eval the code can also have the meaning of forcing global evaluation instead of local evaluation.

function defun(s) { [eval][0](s); }
function defun2(s) { eval(s); }

defun2("function square(x){return x*x}")
---> undefined

square(12)
---> ReferenceError: square is not defined

defun("function square(x){return x*x}")
---> undefined

square(12)
---> 144

See Matteo Tassinari answer link for details (note that the linked article is a bit dated, so ignore details about webkit behavior).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM