为什么(![] + [])[+ !! [] + []]产生“a” [英] Why does (![]+[])[+!![]+[]] produce "a"
问题描述
我有兴趣了解 JavaScript 的内幕。我试过阅读 SpiderMonkey 和 Rhino 但是我的头脑很复杂。
I am interested in understanding the internals of JavaScript. I've tried to read the source for SpiderMonkey and Rhino but it's quite complex to wrap my head around.
我问的原因是:为什么会这样?
The reason I ask is: why does something like
-
(![] + [])[+ !! [] + []]
生成a
-
(Å= [],[μ=!Å+Å] [μ[È= ++Å+Å+Å] +({} +Å)[Ç=! !A +μ,ª= C [A] + C [+!],A] +ª])()[μ[A] +μ[A + A] + C [E] +ª]()
生成alert(1)
?
(![]+[])[+!![]+[]]
produce"a"
(Å=[],[µ=!Å+Å][µ[È=++Å+Å+Å]+({}+Å)[Ç=!!Å+µ,ª=Ç[Å]+Ç[+!Å],Å]+ª])()[µ[Å]+µ[Å+Å]+Ç[È]+ª](Å)
producealert(1)
?
来源: http://sla.ckers.org/forum/read .php?24,32930,page = 1 。
在该论坛上有更多JavaScript奇怪的例子,我想知道它是如何工作的关于Web应用程序安全性的编程观点。
There's many more examples of JavaScript oddities on that forum and I wanted to know how it works from a programming point of view with respect to web application security.
推荐答案
为什么(![] + [ ])[+ !! [] + []]
逐步产生a
:解析如下:(![] + [])
和 [+ !! [] + []]
。第一位已经由artemb解释: []
是一个数组。否定它,![]
计算为布尔值, false
- 这就是!
适用于不是 null
或未定义的内容。再次如artemb所指出的那样,附加此 + []
会强制将布尔值转换为字符串。那是因为 +
是一个字符串连接运算符。然后将布尔 false
转换为其字符串表示形式,false
。
step by step: this is parsed in: (![]+[])
and [+!![]+[]]
. First bit was already explained by artemb: []
is an array. Negating it, ![]
evaluates to a boolean, false
- that's just how !
works when it is applied to something that is not null
or undefined. Again as pointed out by artemb, appending this +[]
forces the boolean to be converted to a string. That's because the +
is a string concatenation operator. The boolean false
is then converted to its string representation, "false"
.
然后,第二位, [+ !! [] + []]
。首先,外部的 [
和]
用于处理前面的字符串,我们刚刚提取的字符串等于false
作为一个字符数组。通过在 [
和]
中放置一个整数索引,可以得到特定索引处的字符。剩下的就是 + !! [] + []
这包括4件: +
, !! []
, +
和 []
。首先评估 !! []
。我们已经看到![]
是一个布尔 false
所以预先加上另一个!
否定它,并且产生 true
。接下来发生的事情是 + !! []
中的 +
被应用,并应用 +
它将布尔值 true
转换为数字表示形式,即 1
(所以 + true
是 1
) + []
那个跟随从 1
再次生成一个字符串1
但是它没有意义,更短的表达式(![] + [])[+ !! []]
已生成 a
。附加 + []
也不会受到影响,结果表达式只是 [1]
而不是 [1]
。我的预感是当 []
应用于数组时, []
中的任何内容都将被强制转换为数字,1
将再次给出 1
。无论哪种方式, + !! [] + []
计算结果为 1
,最后表达式为:false[1]
这就是说:从字符串false
中获取索引1处的字符,并且因为默认情况下,数组在javascript中以 0
开头,这是false的第二个字符
,以及 a
。
Then, the second bit, [+!![]+[]]
. First of all, the outer [
and ]
serve to treat the preceding string, which we just dervived is equal to "false"
as an array of characters. By putting an integer index inside the [
and ]
, you get the character at a particular index. So what remains is +!![]+[]
This consists of 4 pieces: +
, !![]
, +
and []
. First !![]
is evaluated. We already saw that ![]
is a boolean false
so prepending another !
negates it, and yields true
. Next thing what happens is that the +
in +!![]
gets applied, and by applying +
it converts the boolean true
into the number representation, which is 1
(so +true
is 1
) The +[]
that follows makes a string again from that 1
yielding "1"
but it does not really make sense, the shorter expression (![]+[])[+!![]]
already produces a
. Appending +[]
doesn't hurt either, the resulting expression is simply ["1"]
instead of [1]
. My hunch is that when []
is applied to an array, whatever is inside the []
will be coerced into a number, which for "1"
would give 1
again. So either way, +!![]+[]
evaluates to 1
, making the final expression: "false"[1]
which is saying: gimme the character at index 1 from the string "false"
, and since by default, arrays start at 0
in javascript, this is the second character of "false"
, and a
.
这篇关于为什么(![] + [])[+ !! [] + []]产生“a”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!