2012-12-08 10 views
5

Sto caricando un file di testo che contiene una nuova riga e lo inoltro a html/templates.html/templates - Sostituzione newlines con <br>

Sostituendo la \n con <br> nella stringa caricata, sono scappati dal modello in html &lt;br&gt; e visualizzato nel browser, invece di provocare un ritorno di linea.

Come posso modificare questo comportamento senza passare a text/templates (che non ha la protezione XSS)?

risposta

6

Sembra si potrebbe correre template.HTMLEscape() sul tuo primo testo per igienizzare, quindi effettuare il \ n alla sostituzione
di cui ci si fida, quindi utilizzarla come dati del modello pre-escape e attendibili.

Aggiornamento: Ampliando l'esempio di Kocka, questo è quello che avevo in mente:

package main 

import (
    "html/template" 
    "os" 
    "strings" 
) 

const page = `<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
    <p>{{.}}</p> 
    </body> 
</html>` 

const text = `first line 
<script>dangerous</script> 
last line` 

func main() { 
    t := template.Must(template.New("page").Parse(page)) 
    safe := template.HTMLEscapeString(text) 
    safe = strings.Replace(safe, "\n", "<br>", -1) 
    t.Execute(os.Stdout, template.HTML(safe)) // template.HTML encapsulates a known safe HTML document fragment. 
} 

http://play.golang.org/p/JiH0uD5Zh2

uscita è

<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
    <p>first line<br>&lt;script&gt;dangerous&lt;/script&gt;<br>last line</p> 
    </body> 
</html> 

e il testo reso nel browser è

first line 
<script>dangerous</script> 
last line 
3

Non sai dove stai sostituendo \n per <br> ma se è in viaggio, puoi lanciare la stringa come template.HTML in modo che non sia sfuggita.

See: http://golang.org/pkg/html/template/#HTML

Se è in un modello, ci dovrebbe essere un oleodotto a disposizione, {{. | html}}

+0

non posso gettarlo ai 'template.HTML' perché la mia stringa non è sicuro. Potresti elaborare il trucco del pileline? Grazie mille –

+2

se la stringa non è sicura, la pipeline non aiuterà neanche. Prova a dividere la stringa su '" \ n "' e passando la sezione risultante nel modello. Utilizzare 'range' per stampare la stringa e inserire'
'. Ad esempio: 'Arr: = strings.Split (myString," \ n ")' nel codice go e '{{range Arr}} {{.}}
{{end}}' nel modello. – dskinner

+1

@dskinner, so che è tardi, ma dovresti scrivere il tuo come risposta completa. È una soluzione molto più pulita. – Nashenas

2

Puoi farlo in questo modo:

package main 

import (
    "html/template" 
    "os" 
) 

const page = `<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
    <p>{{.}}</p> 
    </body> 
</html>` 

func main() { 
    t := template.Must(template.New("page").Parse(page)) 
    t.Execute(os.Stdout, template.HTML("<br>")) 
} 

Try it out!

+0

Questa è in realtà la traccia corretta --- ma ha visto che l'input non è salvato, il che richiede più elaborazione, come fatto correttamente nella risposta accettata. – JohnDoe

1

Non è necessario far passare l'intero modello come un modello non sicuro (e questa è una cattiva pratica).

È necessario passare una mappa al modello e solo "non sicuri" esplicitamente gli elementi che si desidera utilizzare come tali, ad es.

package main 

import "bytes" 
import "fmt" 
import "html/template" 
import "strings" 

var input = ` 
    {{ define "LAYOUT" }} 
    <html> 
     <body> 
     {{ template "CONTENT" . }} 
     </body> 
    </html> 
    {{ end }} 

    {{ define "CONTENT" }} 
    Unsafe content: {{ .Unsafe }} 
    Newlines converted to <br/> follow: 
    {{ .Normal }} 
    {{ end }} 

    {{ template "LAYOUT" . }} 
` 

var other = ` 
    Hello 
    World 
    Again 
` 

var other2 = ` 
    <script>alert("Owned!");</script> 
` 

func main() { 

    var t, err = template.New("sample").Parse(input) 
    if err != nil { 
     panic(err) 
    } 

    var fixed = strings.Replace(other, "\n", "\n<br/>", -1) 
    var model = map[string]interface{}{ 
     "Normal": template.HTML(fixed), 
     "Unsafe": other2, 
    } 

    var out bytes.Buffer 
    t.Execute(&out, model) # <--- !! Notice the model is NOT an HTML type. 

    var raw = out.String() 
    fmt.Printf("%s", raw) 
} 

Resa:

Unsafe content: &lt;script&gt;alert(&#34;Owned!&#34;);&lt;/script&gt; 

Newlines converted to <br/> follow: 
<br/> Hello 
<br/> World 
<br/> Again 
<br/> 

    </body> 
</html> 
+1

Mentre l'idea è giusta, l'implementazione è sbagliata: contrassegnare una stringa come "sicura" avvolgendola in 'template.HTML (...)' disabilita tutte le altre fughe, quindi ad es. qualsiasi elemento '

Problemi correlati