JSF ** k mit nur 5 Symbolen?

47

Dies ist keine Herausforderung, sondern eine Frage

Nicht-herausfordernde Fragen, die sich auf das Lösen von Programmierpuzzles oder eine bestimmte Art von Herausforderung beziehen, sind ebenfalls ein Thema.

Nun zu der Frage:

Ist es möglich, einen beliebigen JavaScript-Code mit nur 5 Buchstaben zu schreiben? JSFuck macht dies bereits mit 6 Symbolen, !+[]()aber ich frage mich, ob der !Charakter benötigt wird.

JSFuck arbeitet mit einer Kombination aus Casting in String (durch Hinzufügen eines leeren Arrays), Casting in Number (durch Schreiben eines + davor) und Casting in Boolean durch Negieren. Zum Beispiel:

[]        \\ Empty array
+[]       \\ Cast to number -> 0
!+[]      \\ Negate -> true
!+[]+[]   \\ Cast to string -> "true"

Aus dieser Zeichenfolge können wir alle Buchstaben mit Hilfe der eckigen Klammern mit einer Zahl darin extrahieren. Sie können jede Zahl erstellen, indem Sie so oft true addieren.

Auf diese Weise können viele Buchstaben gefunden und zu Zeichenfolgen verknüpft werden. Die wichtigste Zeichenfolge, die erstellt werden muss, ist, "constructor"dass sie zum Abrufen Functionvon Funktionen verwendet werden kann. Mit diesem Objekt können Zeichenfolgen als JavaScript ausgeführt werden:

[]["find"]                          \\ the function Array.prototype.find
[]["find"]["constructor"]           \\ the Function object
[]["find"]["constructor"](string)() \\ same as eval(string)

Wie Sie sehen können, !hat hier 2 Verwendungen:

  • Erstellen von Zahlen zum Auswählen von Buchstaben aus Zeichenfolgen.
  • Casting nach Boolean zu bekommen "true"und "false".

Die erste dieser beiden Methoden kann auch mit dem ++Inkrementor ausgeführt werden, nicht direkt 0, sondern für Elemente innerhalb eines Arrays:

+[]          \\ 0
[+[]]        \\ [0]
[+[]][+[]]   \\ [0][0] -> 0
++[+[]][+[]] \\ ++[0][0]-> 1
++[[]][+[]]  \\ also works because ++ casts to number

So können alle Nummern ohne erstellt werden !.

Der zweite ist schwieriger. Die Bedeutung von "true"und "false"liegt in den Buchstaben "r"und "s", in denen beide vorkommen "constructor". Ich habe bereits alle anderen Buchstaben gefunden "constructor"mittels "undefined", "Infinity", "NaN"und durch Gießen Funktionen in Strings.

Die ultimative Frage lautet also: (Wie) können Sie Boolesche Werte oder Buchstaben "r"und "s"JavaScript nur mithilfe von erstellen +[]()?

Der Brief "l"könnte auch helfen. Es kann in der Form erhalten werden, nullaber ich war nicht in der Lage, diesen Wert mit diesen 5 Symbolen zu erhalten. Es kann zum Beispiel verwendet werden, um Boolesche Werte zu erhalten, wenn wir bereits haben "s":

[]["includes"]()       \\ false
[+[]]["includes"](+[]) \\ true

Der Brief "l"und "k"zusammen würde Zugang geben zu "r":

([]+[])["link"]() \\ "<a href="undefined"></a>"

Jeder Weg, um einen Booleschen Wert nulloder einen der Buchstaben zu erhalten, r s l kwäre sehr nützlich!

Eine Bibliothek von dem, was wir haben:

Array.prototype.find: [] [([] [[]] + []] [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [])]) + ((([] [] + []) [(++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + ( ++ [[]] [+ []]]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] []] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []])]]

Unendlich: + ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ []] [+ []]) + (+ + [[]] [+ []]) + (++ [[]] [+ []])) + (++ [[]] [+ []] + []) + (+ []) + (+ []) + (+ []))

NaN: + [] [[]]

nicht definiert: [][[]]

0: + []

1: ++ [[]] [+ []]

2: (++ [[]] [+ []]) + (++ [[]] [+ []])

3: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

4: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ [[] ] [+ []])

5: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + (++ [] ] [+ []]) + (++ [[]] [+ []])

6: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + (++ [] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

7: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + (++ [] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

8: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + (++ [] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ [[]] [+ []])

9: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + (++ [] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

a: (+ [] [[]] + []) [++ [[]] [+ []]]

c: ([] [([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])]] + []) [(++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]

d: ([] []] + []) [(++ []] [+ []]) + (++ []] [+ []]]

e: ([] []] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ []] [ + []])]

f: ([] []] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ []] [ + []]) + (++ [[]] [+ []])]

i: ([] []] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ []] [ + []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]

n: ([] []] + []) [++ [[]] [+ []]

o: ([] [([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])]] + []) [(++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]

t: (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ []] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []]]) + (++ [[]] [+ []] + []) + (+ [] ) + (+ []) + (+ []) + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [] ])]

o: ([] [[]] + []) [+ []]

v: ([] [([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])]] + []) [(++ []] [+ []]) + (++ [[]] [+ []]) + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]))]

y: (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ []] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []]]) + (++ [[]] [+ []] + []) + (+ [] ) + (+ []) + (+ []) + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [] ]) + (++ [[]] [+ []])]

I: (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ [[]] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []]]) + (++ [[]] [+ []] + []) + (+ [] ) + (+ []) + (+ [])) + []) [+ []]

N: (+ [] [[]] + []) [+ []]

"": ([] [(([] []] + []) [(++ [[]] [+ []]) + (++ []] [+ []]) + (+ + [[]] [+ []]) + (++ [[]] [+ [])] + ((([] []] + []) [(++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []] + (++ [[]] [+ []])] + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [ ]) [(++ [[]] [+ []]) + (++ []] [+ []])]] + []) [+ (++ []] [+ ] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (+ + [[]] [+ []]) + (++ [[]] [+ []])))

(: ([] [([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ []] [+ []])]] + []) [+ (++ []] [+ [] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]))]

): ([] [(([] []] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ []] [+ []])]] + []) [+ (++ []] [+ [] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []] + (++ [[]] [+ []])))]

{: ([] [([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ []] [+ []])]] + []) [+ (++ []] [+ [] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]))]

}: ([] [([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ((([] []] + []) [(++ []] [+ [ ]]) + (++ [[]] [+ []]) + (++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])]] + []) [+ ((++ []] [+ [] ]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + [] + ((++ []] [+ []]) + ( ++ [[]] [+ []])))]

.: (+ (++ [[]] [+ []] + [] + (++ [[]] [+ []]) + ([] [[] + []) [(++ [ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]] + (++ []] [+ [] ] + [] + (+ []) + (+ [])) + []) [++ [[]] [+ []]

,:[[]] [([] [([] [[]] + []) [(++ [[]] [+ []]) + (++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [])]) + ((([] [] + []) [(++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + ( ++ [[]] [+ []]]) + (([] [[]] + []) [++ [[]] [+ []]) + (([] []] + []) [(++ [[]] [+ []]) + (++ []] [+ []])]] + []) [(++ []] [+ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]] + ([] [(([] [[]] + []) (++ [[]] [+ []]) + (++ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [ + []])]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ []] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [])] + (([] [] ] + []) [++ [[]] [+ []]] + (([] [[]] + []) [(++ []] [+ []] + (++ [[]] [+ []])]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []] )] + ([] [[]] + []) [++ []] [+ []] + ([] [(([] [] + []) [(++ [ ]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) ]) + (([] [[]] + []) [(++ []] [+ []]) + (++ []] [+ []] + (++ [] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])] + (([] []] + []) [++ [[]] [+ []]]) + (([] []] + []) [(++ []] [+ []]) + (++ [[]] [ + []])])] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []]] + (+ [] [[]] + []) [++ [[]] [+ []] + (+ ((++ [[]] [+ []] + []) + (([] []] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + ( ++ [[]] [+ []] + []) + (+ []) + (+ []) + (+ []) + []) [(++ []] [+ [] ]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ []] [+ []] + (++ [ ]] [+ []]) + (++ [[]] [+ []])] ([[]]) + []
Jens Renders
quelle
Dies hängt sehr eng mit codegolf.stackexchange.com/q/11690/194 zusammen , und wenn diese Frage eine Antwort von JS hätte, hätte ich dafür gestimmt, sie zu schließen. So wie es ist, wird eine Antwort auf diese Frage wahrscheinlich direkt in eine Antwort auf die frühere Frage übersetzt, aber der Unterschied macht sie so grenzwertig, dass ich nicht einseitig schließen möchte.
Peter Taylor
29
Sehr nette Frage. Ich bin absolut dafür, Fragen zu esoterischer Programmierung und unkonventionellen Rechenmodellen zu stellen , aber seien Sie auf ein enges Abstimmen vorbereitet, da dies derzeit nicht in den Bereich passt, über den sich die Leute auf Meta einigen. Ich würde es lieben, wenn dies einen Präzedenzfall für solche Fragen darstellt. :)
Martin Ender
1
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Alex A.
4
Fragen wie diese lassen mich wünschen, dass es eine Funktion gibt, die einer Frage ein Kopfgeld gibt.
Xnor
1
Ich habe evalin 2453 Zeichen mit windowerlaubt.
CalculatorFeline

Antworten:

23

Nach dem Brainstorming scheint das Ergebnis zu sein, dass es zumindest auf modernen Browsern keine Möglichkeit gibt, dies zu tun.

Ich werde versuchen, den gesamten Prozess zusammenzufassen und einige Überlegungen anzustellen, warum wir unsere Optionen in einem bestimmten Bereich ausgeschöpft haben, bevor wir fortfahren. Abgesehen von einer erstaunlichen neuen Einsicht (wie zum Beispiel einem Eckfall der JavaScript-Syntax, den jeder vergisst) wird es dann ziemlich klar sein, dass es keine Möglichkeit gibt, an die verbleibenden Buchstaben zu kommen.

Literale

Die einzigen unmittelbaren Literale Sie machen +()[]die verschachtelten leere Arrays sind [], [[]], [[[]]]etc. Von dort aus können wir Guss Werte beginnen +:

  • +[]erhält null, was Jens 'Trick mit willkürlich positiven ganzen Zahlen erweitert ++.

  • []+[]ist "". In der Tat []+xbekommt man uns eine String-Darstellung xim Allgemeinen.

[]Die nächste Verwendung ist die Indizierung. Indizieren eines Objekts außerhalb der Grenzen ( [][[]]) bringt Sie undefined. Wenn Sie das in einen String umwandeln und das Ergebnis indizieren, erhalten Sie die Buchstaben d e f i n u. Wenn Sie es zuerst in eine Ganzzahl +umwandeln, erhalten Sie NaN, woraus die Buchstaben a Nfolgen.

Wenn Sie den ++Trick auf einen nicht ganzzahligen Wert anwenden, der bisher erreicht wurde, wird entweder ein Ergebnis NaNoder ein Fehler ausgegeben. Keines der Objekte, die wir erstellen können, ist (noch) aufrufbar, ()hilft also nicht (außer beim Gruppieren).

Die verbleibenden Tricks in unserem Ärmel sind Gießen und Indexieren. Die Frage ist also: Welche Zeichenfolgen können wir mit den Zeichen erstellen, die 0123456789adefinuNentweder

  • sind Zahlenliterale, die wir in Ganzzahlen umwandeln können, um neue Zeichenfolgen zu erhalten, oder
  • sind Eigenschaftsnamen von Objekten, die wir bereits erreichen können?

Anzahl Literale

Als Beispiel für die zweite Option können wir die Zeichenfolge erstellen "1e1000"und dann Infinityvon +"1e1000"abrufen. Wenn wir diese zurück in Zeichenfolge umwandeln, erhalten wir die Buchstaben yund I.

Außerdem können wir machen "11e100", auf Zahl und zurück auf Zeichenkette werfen, um zu bekommen "1.1e+101", aus denen wir extrahieren .und +.

Auf diese Weise .können wir die Zeichenfolge ".0000001"erstellen, sie in Zahlen umwandeln und zurück, um zu "1e-7"gewinnen -.

Das ist im Grunde genommen alles, was Sie mit floats erreichen: Es gibt keine interessanteren Werte als Infinityund NaNund es werden keine weiteren Zeichen in den üblichen Zeichenfolgendarstellungen verwendet als -+.0123456789e.

Eigenschaften

Also haben wir die Briefe -+.0123456789adefinuyIN. Welche Eigenschaften können wir erreichen? Lassen Sie uns nach JavaScript fragen.

>>> R = /^[-+.0123456789adefinuyIN]+$/
>>> [Array, Object, String, Number].reduce((h, f) => {
        h[f.name] = Object.getOwnPropertyNames(f.prototype).filter(x => x.match(R));
        return h }, {})

{ Array: [ 'find' ], Object: [], String: [], Number: [] }

Nur [].find, was Jens schon gefunden hat. Lassen Sie uns das in eine Zeichenfolge umwandeln, alle Buchstaben ernten und es erneut versuchen. Die Zeichenfolgendarstellung ist in den verschiedenen Browsern etwas unterschiedlich. "function find() { [native code] }"Enthält in Chrome und Edge acdefinotuv()[]{}und ein Leerzeichen. Unser vollständiges Alphabet ist jetzt +-.()[]{}0123456789INacdefinotuvy. In Firefox gibt es mehr Leerzeichen und Zeilenumbrüche, aber die Buchstaben sind gleich.

Wir wiederholen unsere Suche:

>>> R = /^[+-.()\[\]{}0123456789INacdefinotuvy]+$/
>>> [Array, Object, String, Number, Function].reduce((h, f) => {
        h[f.name] = Object.getOwnPropertyNames(f.prototype).filter(x => x.match(R));
        return h }, {})

{ Array: [ 'concat', 'find' ],
  Object: [],
  String: [ 'concat' ],
  Number: [],
  Function: [] }

String.prototype.concatist veraltet: es macht genau das +, was wir schon können. Also haben wir Array.prototype.concatund Array.prototype.find. Was können wir mit ihnen machen?

Funktionen

concat()Lässt uns zum ersten Mal längere Arrays erstellen. [[]].concat([[]])ist [[], []], und das Casting zu einer Zeichenfolge bringt uns ",". (Dies hilft uns nicht, neue Eigenschaften zu finden.) Ändert .concatjedoch nicht unsere Werte und kann niemals zurückgegeben werden nulloder ähnliches.

Anrufen find()hilft uns auch nicht: In der MDN-Dokumentation steht

Die find()Methode gibt einen Wert im Array zurück, wenn ein Element im Array die angegebene Testfunktion erfüllt. Andernfalls undefinedwird zurückgegeben.

Beides können wir bereits mit der Indizierung tun.


Und von hier aus kann man nirgendwo anders hingehen. Wenn Sie an etwas zweifeln, das ich geschrieben habe, lassen Sie es mich in den Kommentaren wissen.

Lynn
quelle
1
Meine persönlichen Ansätze , die ich mit in den letzten Stunden allein gearbeitet habe , haben alle machbar ergaben nullRückkehr Funktionen: String.prototype.match, RegExp.exec, und Array.prototype.includes. Als ich feststellte, dass all dies unmöglich zu formen ist, kam ich auch zu dem Schluss, dass es keinen möglichen Weg gibt, dies zu tun, es sei denn, es gibt einen seltsamen Weg, einen Regex zu formen, den ich nicht kenne.
Conor O'Brien
Gute Analyse! Dies ist wahrscheinlich die richtige Antwort, aber ich hoffe immer noch auf einen Trick ... wahrscheinlich falsche Hoffnung :)
Jens Renders
Wenn wir die Buchstaben zum Fangen und Werfen bekommen könnten, könnten wir die Buchstaben des Fehlers bekommen? Das ist 'hwr'.
13.
3
Selbst wenn wir die Zeichenfolgen konstruieren, "catch"und "throw"was wir derzeit nicht können, brauchen wir etwas Ähnliches eval, um diese als Schlüsselwörter zu verwenden, was unser erstes Ziel ist.
Lynn
Negative Zahlen sind mit -und Zahlenumwandlung möglich, aber das ist nicht sehr hilfreich.
CalculatorFeline
15

Die 3 Funktionen in Lynns Antwort waren nicht so nutzlos. Aber der strikte Modus in ECMAScript 5 hat meinen Plan vereitelt.

In den älteren Versionen von JavaScript / ECMAScript gibt es eine Besonderheit. Wird eine Methode ohne Objekt aufgerufen, wird das globale Objekt windowangenommen. Also können wir das machen:

a = {f:function(){return this}};
a.f();                            // Returns a.
g = a.f;
g();                              // Returns window.
window.g();                       // Also returns window.

Dies gilt nach wie vor für moderne Browser, jedoch nur, wenn die Funktion nicht im strengen Modus definiert ist. Und alle eingebauten Funktionen (mit nativem Code) schienen im strengen Modus zu sein. In älteren Browsern, in denen es noch keinen strengen Modus gibt, funktioniert dies auch für integrierte Funktionen.

Angenommen, wir verwenden ältere Browser. Wenn wir dann wollen window, müssen wir eine eingebaute Funktion finden, die etwas zurückgibt, das enthält this. Innerhalb der einzigen Auswahlmöglichkeiten, die wir hatten, gibt es die Funktion Array.prototype.concat, die genau das tut. Wir können es so testen:

Number.prototype.concat = Array.prototype.concat;
1..concat(2);                     // Returns [1, 2]
concat = Array.prototype.concat;
window.concat(2);                 // Returns [window, 2]
concat(2)                         // TypeError in modern browsers while
                                  //   returning the same thing in older ones.
concat.bind(window)(2)            // A workaround in modern browsers.

Im Grunde ist es also egal, ob das Objekt, auf das zugegriffen wird, ein Array ist (aber es muss zumindest ein Objekt sein). Wenn nicht, wird es einfach in ein Array eingeschlossen.

Wenn windowdies der Fall wäre , könnten wir zuerst die Zeichenfolge erhalten, [object Window]indem wir sie in eine Zeichenfolge umwandeln. Mit dem neuen Charakter b, können wir erhalten rund sdie folgenden zwei Zeilen jeweils mit und jeder Charakter , den wir nicht in haben constructor:

window["atob"]("cuaa")[0]
window["atob"]("cyaa")[0]

Das andere Problem ist jedoch, die Objektreferenz von zu entfernen [].concat. Es in ein Array zu packen und zu extrahieren funktioniert nicht, weil das [].concatschon bedeutet []["concat"]. Die einzige Möglichkeit, die ich kenne, um sie zu konstruieren, +[]()besteht darin, sie von einer Funktion zurückzugeben. Array.prototype.findschien dazu in der Lage zu sein:

[[]["concat"]]["find"](x=>1)      // Returns Array.prototype.concat, where x=>1 can
                                  //   be replaced with any always truthy function.

Wir hatten immer wahrheitsgemäße Funktionen. Array.prototype.concatund String.prototype.concatbeide geben die Wahrheit zurück, wenn das Objekt ist window. Wenn wir die spätere verwenden, haben wir alle drei verfügbaren Funktionen verwendet.

Aber leider Array.prototype.findgibt es nicht in dem alten Browser , den wir verwenden. Zumindest habe ich keinen gefunden, der funktioniert. Und ich habe keine andere Möglichkeit gefunden, den Objektverweis zu entfernen.

Der vollständige Code, der in modernen Browsern getestet werden kann, rund smit der .bind(window)Problemumgehung:

[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0]["ato"+([]+[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0])[2]]("cuaa")[0];
[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0]["ato"+([]+[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0])[2]]("cyaa")[0]
jimmy23013
quelle
Coole Infos. Welche Browser haben Sie ausprobiert?
Lynn
@Lynn Nicht viele. Meistens Firefox 3.6.0 und 25.0. Ich habe von hier und hier gelesen , dass findes viel später als im strengen Modus kam, also ist es unwahrscheinlich, dass etwas funktioniert. Ich habe nach Edge gefragt, weil ich dachte, dass es eine Chance gibt, die Abwärtskompatibilität der Befolgung des Standards vorzuziehen. Aus dem gleichen Grund habe ich auch Konqueror ausprobiert. Und einige Befehlszeilen-Browser, aber keiner von ihnen unterstützt sogar JavaScript.
Jimmy23013
Ich habe Safari 7.1 und 8 ausprobiert und einige zufällige vermeintliche Standardbrowser auf Telefonen auf einer Browser-Screenshot-Website. Keiner funktioniert so weit.
Jimmy23013
@ jimmy23013 Probieren Sie Safari 5.0 oder 5.1 aus. Nach Kann ich , teilweise Unterstützung bei älteren Safari bezieht sich auf den strikten Modus noch eine Menge JS zu akzeptieren , die als ungültig betrachtet werden sollte. Obwohl findnoch nicht implementiert, war es vielleicht teilweise? ... Wenn es nur in ihrer Liste wäre ...
mbomb007