Zum Inhalt springen

Escape-Sequenzen

Fast jeder Escaping-Fehler ist ein Kontextfehler statt eines Syntaxfehlers. Das Zeichen ist bekannt – ein Anführungszeichen, ein Backslash, ein Ampersand – und unklar ist, welche der sechs konfliktierenden Regeln anwendbar ist, wo der String landen wird.

Diese Tabelle ist also nach Kontext organisiert, nicht nach Zeichen. Das gleiche Anführungszeichen wird in einer CSV-Zelle verdoppelt, mit Backslash in JSON escaped, in HTML zu " und bleibt völlig allein innerhalb einfacher Anführungszeichen in der Shell. Vier Zeilen, vier Regeln, ein Zeichen.

Die wichtigste Regel ist die, nach der man zuletzt greift: escape an der Grenze, wo der Wert die Kodierung wechselt, und escape ihn nur einmal. Text, der doppelt escaped wird – ein & im Quelltext der Seite, ein \\n in der Ausgabedatei – ist die Signatur eines Wertes, der zwei Encoder durchlaufen hat, die beide davon ausgingen, dass sie erste waren.

JSON-Strings

10

JSON erlaubt genau diese Escapes. Ein wörtliches Newline oder Tab innerhalb eines Strings ist ungültig.

EscapenBedeutetWenn du es brauchstIm Kontext
\""Ein doppeltes Anführungszeichen innerhalb eines Strings"say \"hi\""
\\\Ein wörtlicher BackslashDer Grund, warum Windows-Pfade JSON brechen."C:\\dir"
\//Ein Schrägstrich – optionalRechtlich, aber nicht notwendig; eine Gewohnheit aus dem Einbetten von JSON in <script> Tags."a\/b"
\nU+000AEin Zeilenvorschub"line\nline"
\rU+000DEin Wagen-Rücklauf
\tU+0009Ein Tab
\bU+0008Ein Backspace
\fU+000CEin Seitenvorschub
\u00e9éJedes Zeichen nach seinem vierstelligen Code-Punkt"caf\u00e9"
\ud83d\ude00😀Ein Zeichen über U+FFFF, als Surrogate-PaarJSON hat keine \u{…}-Form, also nehmen astrale Zeichen zwei Escapes.

JSON erlaubt genau diese Escapes. Ein wörtliches Newline oder Tab innerhalb eines Strings ist ungültig.

10

Eine Obermenge von JSON's, plus die Template-Literal-Escapes.

EscapenBedeutetWenn du es brauchstIm Kontext
\''Ein einfaches Anführungszeichen innerhalb eines einfach angeführten Strings
\""Ein doppeltes Anführungszeichen innerhalb eines doppelt angeführten Strings
\``Ein Backtick innerhalb eines Template-Literals
\${${Ein wörtliches ${ innerhalb eines Template-LiteralsOhne den Backslash startet es eine Interpolation.
\nU+000AEin Zeilenvorschub
\xe9éEin Zeichen nach zwei Hex-Ziffern, bis U+00FF
\u00e9éEin Zeichen nach vier Hex-Ziffern
\u{1f600}😀Jeder Code-Punkt, jedoch langeBenötigt kein Surrogate-Paar, anders als die vierstellige Form.
\0U+0000Ein Null-Zeichen
\u2028U+2028Zeilen-SeparatorGültig in einem JS-String, aber nicht in JSON – ein klassischer JSONP-Bruch.

Eine Obermenge von JSON's, plus die Template-Literal-Escapes.

8

Nur & und < müssen streng in Text escaped werden; Anführungszeichen sind innerhalb von Attributen wichtig.

EscapenBedeutetWenn du es brauchstIm Kontext
&amp;&Ein AmpersandEscape dieses zuerst, oder jeder andere Escape verdoppelt sich.
&lt;<Ein Kleiner-als-Zeichen, damit es keinen Tag startet
&gt;>Ein Größer-als-Zeichen
&quot;"Ein doppeltes Anführungszeichen innerhalb eines Attributs
&#39;'Ein einfaches Anführungszeichen innerhalb eines Attributs&apos; funktioniert auch in HTML5, aber die numerische Form ist überall sicher.
&nbsp;U+00A0Ein geschütztes Leerzeichen
&#233;éJedes Zeichen nach seinem Dezimal-Code-Punkt
&#xE9;éJedes Zeichen nach seinem Hex-Code-Punkt

Nur & und < müssen streng in Text escaped werden; Anführungszeichen sind innerhalb von Attributen wichtig.

9

Welche Zeichen escaped werden müssen, hängt davon ab, in welchem Teil der URL sie sitzen.

EscapenBedeutetWenn du es brauchstIm Kontext
%20 Ein Leerzeichen, überall in einer URL gültig
+ Ein Leerzeichen, aber nur in einem Formular-kodierten Query-StringIn einem Pfad-Segment ist dies ein wörtliches Pluszeichen.
%25%Ein wörtliches ProzentzeichenVerpasse dies und der Wert dekodiert zweimal.
%2F/Ein Schrägstrich innerhalb eines einzelnen Pfad-Segments
%3F?Ein Fragezeichen innerhalb eines Wertes
%26&Ein Ampersand innerhalb eines Parameter-Wertes
%3D=Ein Gleichheitszeichen innerhalb eines Parameter-Wertes
%23#Ein Hash, damit es nicht das Fragment startet
%C3%A9éEin Nicht-ASCII-Zeichen, als seine UTF-8-BytesEin Zeichen kann zwei, drei oder vier Prozent-Gruppen werden.

Welche Zeichen escaped werden müssen, hängt davon ab, in welchem Teil der URL sie sitzen.

5

RFC 4180: Feld in Anführungszeichen, verdopple dann jeden Anführungszeichen drin. Backslashes bedeuten nichts.

EscapenBedeutetWenn du es brauchstIm Kontext
"""Ein Anführungszeichen innerhalb eines angeführten Feldes – verdopple es"say ""hi"""
"a,b",Ein Feld mit dem Trennzeichen – anführen das Feld
"a b"U+000AEin Feld mit einem Zeilenumbruch – anführen das Feld
" a" Erhaltung führender oder nachgelagerter LeerzeichenUnverständig trimmen viele Parser sie.
'=SUM(A1)=Stoppe eine Tabellenkalkulation, die die Zelle als Formel ausführtGilt für Werte, die mit =, +, - oder @ beginnen. Dies ist Formel-Injection.

SQL-Literale und Bezeichner

6

Lies diese; schreib sie nicht. Verwende stattdessen parametrisierte Abfragen.

EscapenBedeutetWenn du es brauchstIm Kontext
'''Ein Anführungszeichen innerhalb eines String-Literals – verdopple es'O''Brien'
"order"orderEin reserviertes Wort, das als Spaltenname verwendet wirdDoppelte Anführungszeichen sind der Standard; SQL Server verwendet [Klammern].
`order`orderDas gleiche in MySQL und MariaDB
\%%Ein wörtliches % innerhalb eines LIKE-Musters
\__Ein wörtliches _ innerhalb eines LIKE-Musters
$tag$ … $tag$'PostgreSQL-Dollar-Quoting – kein Escaping drin überhauptNützlich für Körper von Code, wo Verdopplung jedes Anführungszeichens unlesbar ist.

Shell-Argumente

6

Einfache Anführungszeichen sind wörtlich, doppelte Anführungszeichen expandieren noch Variablen.

EscapenBedeutetWenn du es brauchstIm Kontext
'…'$ ` \Alles drin ist wörtlichDie sicherste Quotierung überhaupt – aber sie kann kein einzelnes Anführungszeichen enthalten.
"…"* ? spaceGlobs und Leerzeichen sind sicher, Variablen expandieren immer nochAlways quote variables: "$var", never bare $var.
\ Ein Leerzeichen in einem unzitierten Dateinamen
\$$Ein wörtliches Dollarzeichen innerhalb von doppelten Anführungszeichen
\``Ein wörtliches Backtick, nicht eine Befehlsersetzung
'\'''Ein einfaches Anführungszeichen innerhalb einfacher AnführungszeichenSchließe, escape, öffne wieder – es gibt keine Möglichkeit, es direkt zu verschachteln.

Häufige Fragen

Warum bricht mein JSON auf einem Windows-Dateipfad?
Weil ein Backslash eine Escape-Sequenz in einem JSON-String startet, wird C:\dir als C gelesen, dann eine ungültige Escape-Sequenz. Korrekt geschrieben ist der Wert "C:\\dir" – zwei Backslashes in der Datei, einer im analysierten String. Schrägstriche funktionieren unter Windows auch und vermeiden das Problem ganz.
Ist %20 oder + richtig für ein Leerzeichen in einer URL?
Beides, an verschiedenen Orten. %20 ist überall in einer URL korrekt. Das Pluszeichen bedeutet ein Leerzeichen nur innerhalb eines Query-Strings, der als application/x-www-form-urlencoded kodiert ist – in einem Pfadsegment ist es ein wörtliches Pluszeichen. Verwende %20, wenn du dir unsicher bist, denn es ist überall richtig.
Wie füge ich ein Anführungszeichen in ein CSV-Feld ein?
Umhülle das Feld in Anführungszeichen und verdopple das innere: "say ""hi""". Das ist RFC 4180, und deshalb ist ein CSV voller verdoppelter Anführungszeichen nicht beschädigt. Ein Backslash bedeutet einem konformen CSV-Parser nichts.
Wofür ist der führende Apostroph in der CSV-Formelzeile?
Er entschärft Formel-Injection. Eine Zelle, die mit =, +, - oder @ beginnt, wird ausgeführt wie eine Formel, wenn die Datei in einem Tabellenkalkulationsprogramm geöffnet wird, also wird ein Wert wie =SUM(A1) aus einer nicht vertrauten Quelle zu Code. Ein vorangehendes Apostroph zwingt die Zelle, als Text gelesen zu werden.
Sollte ich SQL von Hand escapen?
Nein. Ein Anführungszeichen zu verdoppeln wird hier dokumentiert, weil du escaped SQL lesen musst, nicht weil du es schreiben solltest – verwende parametrisierte Abfragen und lass den Driver den Wert handhaben. Hand-Escaping ist die Quelle von SQL-Injection, und es gibt keine Version davon, die bei Überprüfung sicher ist.