繁体   English   中英

为什么(![] + [])[+ !! [] + []]产生“a”

[英]Why does (![]+[])[+!![]+[]] produce “a”

我有兴趣了解JavaScript的内部。 我试图阅读SpiderMonkeyRhino的源代码,但是我的头脑很复杂。

我问的原因是:为什么会这样

  • (![]+[])[+!![]+[]]产生"a"
  • (Å=[],[µ=!Å+Å][µ[È=++Å+Å+Å]+({}+Å)[Ç=!!Å+µ,ª=Ç[Å]+Ç[+!Å],Å]+ª])()[µ[Å]+µ[Å+Å]+Ç[È]+ª](Å)产生alert(1)

资料来源: http//sla.ckers.org/forum/read.php?24,32930,page = 1

在该论坛上还有更多关于JavaScript奇怪的例子,我想从编程的角度了解它在Web应用程序安全性方面的工作原理。

如果你想了解为什么那些奇怪的表达式会像他们一样工作,你可以打开firebug控制台并自己做实验。 我做了,我得到了![]false!![]true ,将数组添加到布尔值( false+[]true+[] )会产生该值的字符串版本( false+[]="false" )。

这样表达式归结为:

"false"["1"] 

这显然是“一个”

为什么(![]+[])[+!![]+[]]产生“a”

一步一步:这解析在: (![]+[])[+!![]+[]] 第一位已经由artemb解释: []是一个数组。 否定它, ![]计算为布尔值, false - 这就是如何! 当它应用于非null或未定义的东西时起作用。 再次如artemb所指出的那样,附加此+[]强制将布尔值转换为字符串。 那是因为+是字符串连接运算符。 然后将布尔值false转换为其字符串表示形式"false"

然后,第二位, [+!![]+[]] 首先,外部[]用于处理前面的字符串,我们只是将其作为一个字符数组等于"false" 通过在[]放置一个整数索引,可以得到特定索引处的字符。 剩下的就是+!![]+[]这包括4件: +!![]+[] 首先评估!![] 我们已经看到了![]是一个布尔值false所以先加上另一个! 否定它,并产生true 接下来发生的事情是+ in +!![]被应用,并且通过应用+它将布尔值true转换为数字表示,即1 (所以+true1 )后面的+[]产生一个字符串再次从那个1产生"1"但它没有真正意义,较短的表达式(![]+[])[+!![]]已经产生a 追加+[]也不会造成伤害,结果表达式只是["1"]而不是[1] 我的预感是,当[]应用于数组时, []内的任何内容都会强制转换为数字, "1"将再次赋予1 所以无论哪种方式, +!![]+[]计算结果为1 ,最终表达式为: "false"[1]这就是说:从字符串"false"中获取索引1处的字符,并且默认情况下为数组在javascript中从0开始,这是"false"的第二个字符,和a

为什么(![] + [])[+ !! [] + []]产生“a”

  1. !expr - 在expr上调用ToBoolean并翻转布尔值。 换句话说,当与not运算符一起使用时,诸如空数组之类的truthy值将产生false。
  2. a + b - 两个表达式都通过内部ToPrimitive运行。 如果结果值是字符串,则执行字符串连接。 否则,基元将通过ToNumber运行并添加。 对象的ToPrimitive(包含数组)将尝试toString和valueOf。 Array.prototype.toString充当没有参数的调用连接。 因此, ![] + [] = false + "" = "false"
  3. !![] == true ,一元加运算符将表达式转换为数字,所以1 同样,数组转换为""所以+!![]+[] == "1"
  4. 表达式归结为("false")["1"] == "a"

另一种表达方式可以用类似的方式归结。 它使用unicode字符串来搞砸它并且它更长,但就像直接“解析”一样。

我建议你获取并阅读:

  • ECMAScript标准(ECMA 262),第5版
  • Adobe文档称为“AVM 2概述”,它解释了AVM2虚拟机的体系结构,Adobe Flash及其ActionScript运行在该体系结构上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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