2010-01-20 140 views
11

我有興趣瞭解JavaScript的內部結構。我嘗試閱讀SpiderMonkeyRhino的源代碼,但將頭部纏繞起來相當複雜。爲什麼(![] + [])[+ !! [] + []]產生「a」

我想問的原因是:爲什麼像

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

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

在這個論壇上還有很多關於JavaScript古怪的例子,我想知道它是如何從編程的角度來看web應用程序的安全性。

+0

如果你有興趣在語言是如何工作的,沒有什麼比寫一個編譯器爲它自己 - 這基本上都會教你的語言,它的內部。 – Chii 2010-01-20 09:50:26

+0

感謝您的回覆。我知道Javascript做了一些魔術,但它所做的一些事情是危險的...... – prafulfillment 2010-01-20 18:20:07

回答

12

爲什麼(![]+[])[+!![]+[]]產生 「一」

一步一步:(![]+[])[+!![]+[]]:這是解析。第一位已由artemb解釋:[]是一個數組。否定它,![]評估爲布爾值,false - 這就是!如何應用於非null或未定義的東西。再如artemb指出的,附加+[]強制將布爾值轉換爲字符串。這是因爲+是一個字符串連接運算符。然後將布爾型false轉換爲其字符串表示形式"false"

然後,第二位,[+!![]+[]]。首先,外部[]用於將前面的字符串作爲一個字符數組來處理,我們只是將這個字符串等同於"false"。通過在[]中放入一個整數索引,可以在特定索引處獲得該字符。所以剩下的是+!![]+[] 這包括4件:+,!![],+[]。首先對!![]進行評估。我們已經看到![]是一個布爾型false,因此預先計劃另一個!否定它,併產生true。接下來會發生什麼事是,在+!![]+得到應用,並通過應用+它的布爾true轉換成數字表示,這是1(所以+true1)下面的+[]再次從1產生"1"但使一個字符串它沒有任何意義,較短的表達式(![]+[])[+!![]]已經產生了a。追加+[]也不會傷害,結果表達式只是["1"]而不是[1]。我的直覺是,當[]應用到陣列中,無論是[]內將強制轉換爲數字,這對於"1"將再次給1。因此無論哪種方式,+!![]+[]評估到1,使最終表達式:"false"[1]這就是說:從字符串"false"給我索引1的字符,因爲默認情況下,數組在javascript中開始於0,這是"false"的第二個字符,和a

16

如果你想了解爲什麼這些奇怪的表達式就像他們那樣工作,你可以打開螢火蟲控制檯並試驗自己。我做到了,![]false,!![]true,將數組添加到布爾值(false+[]true+[])生成此值的字符串版本(false+[]="false")。

這樣表達歸結爲:

"false"["1"] 

這顯然是 「一」

+4

這是如何明顯? – medopal 2010-01-20 10:16:41

+0

很明顯,如果你有足夠的時間和創造力,你可以使用這個有限的字符串連接和索引訪問器來創建任意字符串。 – 2010-01-20 10:21:15

+0

@medopal也許不完全明顯:) 它是字母 「a」 中的字符串 「假」( 'F'= 0, 'A'= 1時, 'L'= 2的索引, 'S'= 3 ,'e'= 4)。 – 2010-01-20 10:51:27

1

我建議您獲取和閱讀:

  • ECMAScript標準(ECMA 262),第5版本
  • Adob​​e文檔稱爲「AVM 2概述」,它解釋了AVM2虛擬機的體系結構,其中Adobe Flash及其ActionScript 跑。
2

爲什麼[+ !! [] + []生產的 「一」

  1. !expr([] + []!) - 在EXPR調用ToBoolean和翻轉布爾值。換句話說,truthy值(如空數組)在與not運算符一起使用時將產生false。
  2. a + b - 兩個表達式都通過內部ToPrimitive運行。如果結果值是一個字符串,則執行字符串連接。否則,原語通過ToNumber運行並添加。 ToPrimitive for objects(包含數組)將嘗試toString和valueOf。 Array.prototype.toString充當沒有參數的調用連接。因此,![] + [] = false + "" = "false"
  3. !![] == true,一元加號操作者轉換表達式的數字,所以1。再次,數組轉換爲"",所以+!![]+[] == "1"
  4. 表達歸結爲("false")["1"] == "a"

其它表達可以以類似的方式可以歸結。它使用unicode字符串來解決它,並且它更長,但就像「解析」一樣簡單。

相關問題