26

Wir bauen eine App auf, die erste mit Rails 3, und wir müssen I18n von Anfang an erstellen. Da wir Perfektionisten sind, wollen wir eine echte Typografie in unseren Ansichten verwenden: Striche, eingerollte Zitate, Ellipsen und so weiter.Verhindern, dass HTML-Zeichenentitäten in Gebietsschema-Dateien durch Rails3-XSS-Schutz verloren gehen

Das bedeutet in unserem locales/xx.yml Dateien, die wir haben zwei Möglichkeiten:

  1. Verwenden echte UTF-8 Inline-Zeichen. Sollte funktionieren, aber schwer zu tippen, und erschreckt mich aufgrund der Menge an Software, die immer noch unartig Dinge zu Unicode.
  2. Verwenden Sie HTML Zeichen Entitäten (& # 8217; & # 8212; usw.). Einfacher zu schreiben, und wahrscheinlich mehr kompatibel mit Fehlverhalten Software.

ich eher die zweite Option nehmen würde, aber die Auto-Flucht in Rails 3 macht dies problematisch, da die Et-Zeichen in der YAML erhält automatisch umgewandelt in Zeichenentität selbst, was zu einem ‚sichtbaren‘ & 8217; s im Browser.

Offensichtlich kann dies umgangen werden, indem raw auf Strings, das heißt:

raw t('views.signup.organisation_details') 

Aber wir sind nicht glücklich, die Route der global raw -ing jedes Mal hinunter wir t etwas wie es uns offen lässt einen Fehler machen und ein XSS-Loch erzeugen. Wir könnten selektiv raw Strings, von denen wir wissen, dass sie Zeichenentitäten enthalten, aber das wäre schwer zu skalieren und fühlt sich einfach falsch an - außerdem könnte eine Zeichenkette, die eine Entität in einer Sprache enthält, in einer anderen Sprache nicht vorkommen.

Irgendwelche Vorschläge auf einer cleveren Schienen-y-Weise, um das zu beheben? Oder sind wir dazu verdammt, Typografie, XSS-Löcher, Stunden vergeblicher Anstrengung oder alles zu verpatzen?

+2

, die eine gute Frage. Ich freue mich auf eine gute Antwort. –

Antwort

32

Es gibt eine ticket in lighthouse für dieses Problem, und die Auflösung ist _html zum i18n Schlüssel in der locales/xx.yml Datei anhängen und verwenden Sie die t alias eine html_safe Zeichenfolge zu bezeichnen. Zum Beispiel:

en: 
    hello: "This is a string with an accent: ó" 

wird:

en: 
    hello_html: "This is a string with an accent: ó" 

Und es würde die folgende Ausgabe erzeugen:

Dies ist ein String mit einem Akzent: & oacute;

Dies würden Sie davon ab, schreiben raw t('views.signup.organisation_details') verhindern und in einem sauberen Ausgang führen würde: t('views.signup.organisation_details_html'). Und während der Austausch von raw für _html nicht wie der größte Handel aussieht, macht es Dinge klar, dass Sie ausgeben, was als eine html_safe-Zeichenfolge angenommen wird.


ich den Code getestet haben im Leuchtturm Ticket vorgeschlagen. Was ich fand, war, dass Sie speziell den t Alias ​​verwenden mussten. Wenn Sie I18n.t oder I18n.translate die Übersetzung verwendet nicht behandeln _html als html_safe:

I18n.t('hello_html') 
I18n.translate('hello_html') 
# Produces => "This is a string with an accent: ó" 

t('hello_html')  
# Produces => "This is a string with an accent: ó" 

Ich glaube nicht, das das beabsichtigte Verhalten gemäß dem RoR TranslationHelper documentation ist.

8

Gut. Ich habe diese Frage gestern wegen des i18n-Winkels mit einem Lesezeichen versehen, aber ich habe sie nicht beantwortet, da ich eine Python-Person bin, die Rails nie benutzt hat. Ich werde es immer noch nicht beantworten, aber da du nicht von hilfreichen Railsianern überrannt wirst, die dich auf eine gute Art und Weise auf Rails Innereien aufmerksam machen könnten, hier ist meine Perspektive.

Zuerst denke ich, es ist groß, dass Sie von Anfang an über das Problem denken. Das ist ziemlich selten. Zweitens stimme ich vollkommen zu, dass rohe Streicher verwendet werden oder selektiv Strings mit Entitäten ausgewählt werden, um Klängen wie einem spröden, hässlichen, fehleranfälligen Hack eine spezielle Behandlung zu geben.

Jetzt, wenn ich Rails richtig verstehe (ich lese this i18n guide), enthalten die YAML-Dateien die lokalisierte Zeichenfolge für jede Sprache. In diesem Fall würde ich dringend empfehlen, normale Zeichen in ihnen zu verwenden (in UTF-8). Ansonsten, Lokalisierungen beibehalten, oder sogar lesen durch eine Übersetzungsdatei - denken Sie an Sprachen in nicht-lateinischen Skripten! - Wird die Hölle sein.

Ja, es würde bedeuten, dass Sie Eingabemethoden herausfinden müssen, aber die Lösung ist sauber und unkompliziert.

+0

yup, legen Sie einfach die vollständigen UTF-8-codierten Zeichen in der Datei. Es ist das, was die Java-Leute seit den Dinosauriern gemacht haben - schau in all ihren Sprachdateien .properties und du wirst die nativen Kodierungen sehen. –

+0

+1, stimme ich voll und ganz zu. –

+1

Rückblickend denke ich, dass dies vielleicht die beste Lösung ist. Ich weiß nicht, warum ich vor drei Jahren so abgeneigt war. –

0

Kennen Sie die html_safe-Methode, die in Helfern verwendet werden kann? Ich bin nicht sicher, ob ich das Problem hier vollständig verstehe, da ich nie mit I18n gearbeitet habe, aber wäre es möglich, einen benutzerdefinierten Helfer zu verwenden, der festlegt, ob die Zeichen nicht maskiert werden sollen und "string" .html_safe zurückgibt entkomme, gib "string" zurück.

Oder vielleicht das „t“ Helfer außer Kraft setzen und fügen Sie Ihre Flucht logischen Bedingungen + .html_safe

+0

Ich weiß nicht genug über das Problem selbst (und den 'Rails Way'), um zu wissen, ob dies ein guter Plan oder eine andere Straße zum Ruin ist, aber danke für den Gedanken ... Könnte es ausprobieren und euch wissen lassen wie es geht. –

0

Ich denke, es ist keine gute Idee ist die Verwendung „raw“ zu verwenden, können Sie mit yml Zeichenfolge wie diese

versuchen
en: 
    hello: 
    This generates a text paragraph for HTML. " " à @ ' All this text, which you can find in 
    these lines, is being concatenated together to one single text node, and then put 
    into the body of the <p> ... </p> tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕ 

HTML

This generates a text paragraph for HTML. &quot; &quot; à @ ' All this text, which you can find in these lines, is being concatenated together to one single text node, and then put into the body of the &lt;p&gt; ... &lt;/p&gt; tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕ 

Browser-Ansicht

This generates a text paragraph for HTML. " " à @ ' All this text, which you can find in these lines, is being concatenated together to one single text node, and then put into the body of the <p> ... </p> tag. ↂↀऊᎣᏍᏮ⁜℺℻⊛⍟⎬⎨⏏♞♝⚫⚬✱✰✭❺❻➣➱➲⬡⬕ 
1

Wenn Sie die Möglichkeit eines Fehlers nicht einfach durch Hinzufügen von .html_safe (durch alias_method_chain oder w/e) zu allem offenbaren wollen, ist die beste Lösung, es einfach zu verwenden, wann immer es notwendig ist.

In unserer Website verwenden wir Markup-Sprache, um HTML-Ausgabe von i18n Locale-Dateien zu erhalten, da wer diese Dateien übersetzt, sind keine Entwickler, nur Übersetzer.

Wenn es nur an wenigen Stellen ist, dass Sie HTML benötigen, um wirklich HTML zu sein, verwenden Sie.html_safe

t('views.signup.organisation_details').html_safe 

Die einfache Markup-Sprache, die wir funktionieren ziemlich gut für uns, aber das ist wirklich fallspezifische :)

Verwandte Themen