2012-12-08 16 views
5

के साथ नई लाइनों को प्रतिस्थापित करना मैं एक टेक्स्ट फ़ाइल लोड कर रहा हूं जिसमें इसमें नई लाइनें हैं, और इसे html/templates पर पास करें।एचटीएमएल/टेम्पलेट्स - <br>

लोड स्ट्रिंग में <br> साथ \n स्थानापन्न, वे बजाय एक लाइन वापसी पैदा करने में, टेम्पलेट सहायता से निकले रहे &lt;br&gt; HTML करने के लिए और ब्राउज़र में प्रदर्शित।

text/templates पर स्विच किए बिना मैं इस व्यवहार को कैसे बदल सकता हूं (जिसमें XSS सुरक्षा नहीं है)?

उत्तर

6

ऐसा लगता है कि आप इसे साफ़ करने में पहले अपने पाठ पर template.HTMLEscape() चला सकते हैं, तो कार्य करें:

देखें \ n से
प्रतिस्थापन जिसे आप भरोसा करते हैं, फिर इसे पूर्व-बच निकले और भरोसेमंद टेम्पलेट डेटा के रूप में उपयोग करें।

अद्यतन:

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

आउटपुट है

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

और पाठ ब्राउज़र में गाया

है: Kocka के उदाहरण पर विस्तार, यह क्या मैं मन में था है
first line 
<script>dangerous</script> 
last line 
3

सुनिश्चित नहीं हैं कि जहां <br> के लिए \n प्रतिस्थापन कर रहे हैं लेकिन अगर यह जाने में है, तो आप template.HTML के रूप में स्ट्रिंग तो वह भागे तो नहीं कर रहा है डाल सकता। http://golang.org/pkg/html/template/#HTML

यदि यह एक टेम्पलेट में है, वहाँ एक पाइप लाइन उपलब्ध होना चाहिए, {{. | html}}

+0

मैं क्योंकि मेरे स्ट्रिंग सुरक्षित नहीं है 'template.HTML' करने के लिए इसे डाली नहीं कर सकता। क्या आप पाइललाइन चाल का विस्तार कर सकते हैं? बहुत स्ट्रिंग –

+2

यदि स्ट्रिंग सुरक्षित नहीं है तो पाइपलाइन या तो मदद करने वाली नहीं है। स्ट्रिंग को '\ n "' पर विभाजित करने का प्रयास करें और परिणामी टुकड़ा को टेम्पलेट में पास कर दें। स्ट्रिंग को मुद्रित करने के लिए 'श्रेणी' का उपयोग करें और'
'डालें। 'आगमन: उदाहरण के लिए: = strings.Split (myString," \ n ")' जाने कोड में, और '{{रेंज आगमन}} {। {}} {{
अंत}}' में टेम्पलेट। – dskinner

+1

@ डस्किनर, मुझे पता है कि यह देर हो चुकी है, लेकिन आपको अपनी पूरी प्रतिक्रिया के रूप में लिखना चाहिए। यह एक बहुत साफ समाधान है। – Nashenas

2

आप इस तरह यह कर सकते हैं:

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

यह वास्तव में सही ट्रैक है --- लेकिन देखा, कि इनपुट सहेजा नहीं जाता है, जिसके लिए अधिक प्रसंस्करण की आवश्यकता होती है, जैसा कि स्वीकृत उत्तर में सही ढंग से किया जाता है। – JohnDoe

1

यह एक असुरक्षित टेम्पलेट के रूप में अपने पूरे टेम्पलेट पारित करने के लिए अनावश्यक है (और यह बुरा व्यवहार होता है)।

आपको अपने टेम्पलेट में एक नक्शा पास करना चाहिए, और केवल उन तत्वों को स्पष्ट रूप से 'असुरक्षित' करना चाहिए जिन्हें आप उपयोग करना चाहते हैं, उदाहरण के लिए।

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) 
} 

पैदावार:

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

जबकि विचार सही है, कार्यान्वयन गलत है: स्ट्रिंग को "टेम्पलेट" के रूप में चिह्नित करना 'टेम्पलेट' में लपेटकर। HTML (...) 'अन्य सभी भागने को अक्षम करता है, उदाहरण के लिए। किसी भी सिंगल-लाइन '

संबंधित मुद्दे