Escape-String im Eval-Kontext mit JSON.stringify

Nov 13 2020

Zuallererst: Ich weiß, dass es viele Fragen im Zusammenhang mit der Flucht gibt, aber ich habe bisher keine allgemein funktionierende Antwort gefunden. Angenommen, ich habe diese einfache Spielzeugfunktion zur Demonstration:

function f(somePOJO) {
  var s = eval("'" + JSON.stringify(somePOJO) + "';"); // for demonstration only
  return JSON.parse(s);
}
const clone = f({a: 1, b: "c"});

Wenn ein Objektliteral wie {a: 1, b: "c"}(ein POJO) gegeben ist, fsollte ein "Klon" davon zurückgegeben werden. (Beachten Sie, dass ich diesen Ansatz nicht wirklich zum Klonen oder Ähnlichem verwende, und mir ist bewusst, dass dies evalböse ist und dass es hier nicht einmal benötigt wird, sondern nur zur Demonstration des Fluchtproblems!)

Dies funktioniert einwandfrei, jedoch nur solange die POJO-Werte kein a enthalten '. Jetzt könnte ich natürlich dem JSON entkommen, indem ich so etwas benutze JSON.stringify(somePOJO).replace(/'/g, "\\'"). Dies funktioniert, wenn die POJO-Werte enthalten ', aber nicht, wenn sie enthalten \\'. Und das schafft eine Spirale der Flucht ...

Gibt es überhaupt eine Lösung dafür?

Antworten

1 traktor Nov 13 2020 at 14:01

Die Escape-Funktion zum Beibehalten einer JSON-Zeichenfolge durch Auswertung durch die evalFunktion, den JavaScript-Compiler unter bestimmten Umständen oder durch die JSON.parseFunktion ist tatsächlich JSON.stringify. Mit dieser JSONMethode werden Zeichenfolgenwerte und nicht nur Objektdatentypen gerne stringifiziert.

function f(somePOJO) {
  var s = eval( JSON.stringify(JSON.stringify(somePOJO)) );
  return JSON.parse(s);
}
const obj = {a: 1, b: "c", d: "back\\, forward/"}
const clone = f(obj);
console.log(obj);
console.log(clone);

Der Grund, warum es nicht zur escape/encodeURI/encodeURIComponentFunktionsfamilie gehört, besteht darin, dass diese Zeichen für die Aufnahme in URLs maskiert werden, während in diesem Fall Zeichen maskiert werden, die von einem JavaScipt-Parser analysiert werden sollen.

In den meisten Fällen, insbesondere um JSON-Text mit zu analysieren JSON.parse, ist es einfach nicht erforderlich, JSON-Text ein zweites Mal zu stringieren und zweimal zu analysieren .

Von etwas akademischem Interesse, aber vor der Einführung JSONin Javascript, könnte man einen String durch serielle Überprüfung seiner Zeichen und Backslash-Escape-Backslashes, mindestens einer Art von Anführungszeichen und Unicode-Escape-Escape-Steuercodes stringifizieren - der gestellten Frage fehlt möglicherweise der Teil über die Notwendigkeit, Backslash-Zeichen sowie Anführungszeichen zu entkommen.