2013-03-13 7 views
6

sagen, dass ich den folgenden Code haben:den Array-Konstruktor Neudefinition in Javascript

var secrets; 
Array = function() { 
    secrets = this; 
}; 

Der Autor der obigen Probe sagt, dass der Code den Array-Konstruktor neu definiert. Erstens bin ich mir nicht sicher, was die this betrifft. Kann jemand bitte beraten?

Zweitens: Wäre der folgende Code äquivalent?

var secrets; 
function Array() { 
    secrets = this; 
} 

Durch die Art und Weise der obige Code aus dem folgenden Artikel über eine Json Verwundbarkeit genommen wird: see here

+3

Sie stellen hier zwei Fragen. Wie das funktioniert, wird in der MDN-Dokumentation erklärt (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this) (kurz: der Wert hängt davon ab, wie die Funktion ist.) genannt) und ob 'Array = function() ...' oder 'function Array() ...' das gleiche ist [in dieser Frage] beantwortet (http://stackoverflow.com/q/336859/218196). –

+0

danke Felix. In Bezug auf "das" habe ich die Dokumentation gelesen, konnte aber nicht herausfinden, worauf sich "das" im obigen Kontext bezieht ** ... Können Sie oder jemand anders helfen? Bezüglich des zweiten Teils meiner Frage habe ich den Beitrag gelesen, den Sie mir gegeben haben, und ich verstehe jetzt besser. – balteo

+1

Wenn Sie 'Array' mit' new' aufrufen, dann verweist es auf ein leeres Objekt, das von 'Array.prototype' erbt. Wenn es ohne 'new' aufgerufen wird, bezieht es sich auf' window'. Wenn es über '.call' oder' .apply' aufgerufen wird, verweist es auf das Element, das als erstes Argument übergeben wird. Um zu wissen, wie es heißt, muss man sich 'JSON.parse' anschauen. –

Antwort

5

In beiden Beispielen definieren Sie die Variable Array als function, die this an secrets zuweist. Es ist einfach so, dass bereits ein globales Objekt namens Array vorhanden ist, das andere JS auf der Seite möglicherweise als Constructor verwenden, um Arrays zu erstellen. Wenn Sie in Ihre Konsole wechseln und Array als etwas anderes zuweisen, erhalten Sie möglicherweise Fehler von Code, der explizit von Array abhängt. Arrays, die wörtlich mit [] gemacht wurden, funktionieren jedoch weiterhin gut, und tatsächlich zeigt ihre __proto__ immer noch, was Array.prototype war. Also:

var arr1 = new Array('a','b','c'); 
// arr[0] -> 'a' 

var arr2 = ['d','e','f']; 
// arr[0] -> 'd' 

var secrets; 
Array = function() { secrets = this; }; 

var arr3 = new Array('g','h','i'); // nothing wrong here, because Array is a function 
// arr3[0] -> undefined 
// Array is just a function, you can't make arrays with new Array anymore 
// and arr3 is just a function 


var arr4 = ['j','k','l']; 
// arr4[0] -> 'j' 
// making array literals still works 

wie für this, nichts Ungewöhnliches, folgt noch die Regeln des this. Die Tatsache, dass Sie Array eine Funktion zuweisen, ändert nicht, wie sich this verhält. so this Punkte auf das globale Objekt, das im Browser window ist, wenn Sie mit new instanziiert oder verwenden call oder apply

der Unterschied zwischen den beiden Proben ist der Unterschied zwischen einem Funktionsausdruck und Funktionsdeklaration finden Sie unter: What is the difference between a function expression vs declaration in Javascript?

1

Ja, beide Schnipsel gleichwertig sind. Beide definieren den Array-Konstruktor neu, um alle Array-Daten abzufangen, die von der Website verwendet werden, auf der sie injiziert wird, wie in dem verlinkten Artikel erläutert. Der Wert von this soll das neu konstruierte Array sein.

Dies scheint von ECMAScript 3 erlaubt worden zu sein, aber nicht von ECMAScript 5, das jetzt in allen modernen Browsern verfügbar ist. Der im Artikel beschriebene Exploit sollte also nicht mehr funktionieren.

+0

Der Exploit funktioniert einfach nicht mehr, da standardkonforme JSON.parse oder Literale 'Array' nicht aufrufen. Siehe meine Antwort zu http://stackoverflow.com/q/13040367/1048572 – Bergi

+0

Ja, das ist, was ich meinte. Zuvor würde etwas wie 'eval ('[1,2,3]')' den neu definierten Konstruktor aufrufen. – bfavaretto

+0

aber es würde immer noch auf Arrays arbeiten, die mit 'new Array()' – C5H8NNaO4

Verwandte Themen