aboutsummaryrefslogtreecommitdiff
path: root/src/html
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2022-02-03 14:12:08 -0500
committerRuss Cox <rsc@golang.org>2022-04-11 16:34:30 +0000
commit19309779ac5e2f5a2fd3cbb34421dafb2855ac21 (patch)
tree67dfd3e5d96250325e383183f95b6f5fe1968514 /src/html
parent017933163ab6a2b254f0310c61b57db65cded92e (diff)
downloadgo-19309779ac5e2f5a2fd3cbb34421dafb2855ac21.tar.xz
all: gofmt main repo
[This CL is part of a sequence implementing the proposal #51082. The design doc is at https://go.dev/s/godocfmt-design.] Run the updated gofmt, which reformats doc comments, on the main repository. Vendored files are excluded. For #51082. Change-Id: I7332f099b60f716295fb34719c98c04eb1a85407 Reviewed-on: https://go-review.googlesource.com/c/go/+/384268 Reviewed-by: Jonathan Amsterdam <jba@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/html')
-rw-r--r--src/html/template/context.go4
-rw-r--r--src/html/template/doc.go132
-rw-r--r--src/html/template/error.go17
-rw-r--r--src/html/template/escape.go12
-rw-r--r--src/html/template/html.go10
-rw-r--r--src/html/template/template.go2
-rw-r--r--src/html/template/url.go18
7 files changed, 102 insertions, 93 deletions
diff --git a/src/html/template/context.go b/src/html/template/context.go
index aaa7d08359..a97c8be56f 100644
--- a/src/html/template/context.go
+++ b/src/html/template/context.go
@@ -79,7 +79,9 @@ func (c context) mangle(templateName string) string {
// HTML5 parsing algorithm because a single token production in the HTML
// grammar may contain embedded actions in a template. For instance, the quoted
// HTML attribute produced by
-// <div title="Hello {{.World}}">
+//
+// <div title="Hello {{.World}}">
+//
// is a single token in HTML's grammar but in a template spans several nodes.
type state uint8
diff --git a/src/html/template/doc.go b/src/html/template/doc.go
index 650e7147a3..5d1631b266 100644
--- a/src/html/template/doc.go
+++ b/src/html/template/doc.go
@@ -12,14 +12,14 @@ The documentation here focuses on the security features of the package.
For information about how to program the templates themselves, see the
documentation for text/template.
-Introduction
+# Introduction
This package wraps package text/template so you can share its template API
to parse and execute HTML templates safely.
- tmpl, err := template.New("name").Parse(...)
- // Error checking elided
- err = tmpl.Execute(out, data)
+ tmpl, err := template.New("name").Parse(...)
+ // Error checking elided
+ err = tmpl.Execute(out, data)
If successful, tmpl will now be injection-safe. Otherwise, err is an error
defined in the docs for ErrorCode.
@@ -34,38 +34,37 @@ provided below.
Example
- import "text/template"
- ...
- t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
- err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
+ import "text/template"
+ ...
+ t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
+ err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
produces
- Hello, <script>alert('you have been pwned')</script>!
+ Hello, <script>alert('you have been pwned')</script>!
but the contextual autoescaping in html/template
- import "html/template"
- ...
- t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
- err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
+ import "html/template"
+ ...
+ t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
+ err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
produces safe, escaped HTML output
- Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
+ Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
-
-Contexts
+# Contexts
This package understands HTML, CSS, JavaScript, and URIs. It adds sanitizing
functions to each simple action pipeline, so given the excerpt
- <a href="/search?q={{.}}">{{.}}</a>
+ <a href="/search?q={{.}}">{{.}}</a>
At parse time each {{.}} is overwritten to add escaping functions as necessary.
In this case it becomes
- <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a>
+ <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a>
where urlescaper, attrescaper, and htmlescaper are aliases for internal escaping
functions.
@@ -73,117 +72,113 @@ functions.
For these internal escaping functions, if an action pipeline evaluates to
a nil interface value, it is treated as though it were an empty string.
-Namespaced and data- attributes
+# Namespaced and data- attributes
Attributes with a namespace are treated as if they had no namespace.
Given the excerpt
- <a my:href="{{.}}"></a>
+ <a my:href="{{.}}"></a>
At parse time the attribute will be treated as if it were just "href".
So at parse time the template becomes:
- <a my:href="{{. | urlescaper | attrescaper}}"></a>
+ <a my:href="{{. | urlescaper | attrescaper}}"></a>
Similarly to attributes with namespaces, attributes with a "data-" prefix are
treated as if they had no "data-" prefix. So given
- <a data-href="{{.}}"></a>
+ <a data-href="{{.}}"></a>
At parse time this becomes
- <a data-href="{{. | urlescaper | attrescaper}}"></a>
+ <a data-href="{{. | urlescaper | attrescaper}}"></a>
If an attribute has both a namespace and a "data-" prefix, only the namespace
will be removed when determining the context. For example
- <a my:data-href="{{.}}"></a>
+ <a my:data-href="{{.}}"></a>
This is handled as if "my:data-href" was just "data-href" and not "href" as
it would be if the "data-" prefix were to be ignored too. Thus at parse
time this becomes just
- <a my:data-href="{{. | attrescaper}}"></a>
+ <a my:data-href="{{. | attrescaper}}"></a>
As a special case, attributes with the namespace "xmlns" are always treated
as containing URLs. Given the excerpts
- <a xmlns:title="{{.}}"></a>
- <a xmlns:href="{{.}}"></a>
- <a xmlns:onclick="{{.}}"></a>
+ <a xmlns:title="{{.}}"></a>
+ <a xmlns:href="{{.}}"></a>
+ <a xmlns:onclick="{{.}}"></a>
At parse time they become:
- <a xmlns:title="{{. | urlescaper | attrescaper}}"></a>
- <a xmlns:href="{{. | urlescaper | attrescaper}}"></a>
- <a xmlns:onclick="{{. | urlescaper | attrescaper}}"></a>
+ <a xmlns:title="{{. | urlescaper | attrescaper}}"></a>
+ <a xmlns:href="{{. | urlescaper | attrescaper}}"></a>
+ <a xmlns:onclick="{{. | urlescaper | attrescaper}}"></a>
-Errors
+# Errors
See the documentation of ErrorCode for details.
-
-A fuller picture
+# A fuller picture
The rest of this package comment may be skipped on first reading; it includes
details necessary to understand escaping contexts and error messages. Most users
will not need to understand these details.
-
-Contexts
+# Contexts
Assuming {{.}} is `O'Reilly: How are <i>you</i>?`, the table below shows
how {{.}} appears when used in the context to the left.
- Context {{.}} After
- {{.}} O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?
- <a title='{{.}}'> O&#39;Reilly: How are you?
- <a href="/{{.}}"> O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
- <a href="?q={{.}}"> O&#39;Reilly%3a%20How%20are%3ci%3e...%3f
- <a onx='f("{{.}}")'> O\x27Reilly: How are \x3ci\x3eyou...?
- <a onx='f({{.}})'> "O\x27Reilly: How are \x3ci\x3eyou...?"
- <a onx='pattern = /{{.}}/;'> O\x27Reilly: How are \x3ci\x3eyou...\x3f
+ Context {{.}} After
+ {{.}} O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?
+ <a title='{{.}}'> O&#39;Reilly: How are you?
+ <a href="/{{.}}"> O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
+ <a href="?q={{.}}"> O&#39;Reilly%3a%20How%20are%3ci%3e...%3f
+ <a onx='f("{{.}}")'> O\x27Reilly: How are \x3ci\x3eyou...?
+ <a onx='f({{.}})'> "O\x27Reilly: How are \x3ci\x3eyou...?"
+ <a onx='pattern = /{{.}}/;'> O\x27Reilly: How are \x3ci\x3eyou...\x3f
If used in an unsafe context, then the value might be filtered out:
- Context {{.}} After
- <a href="{{.}}"> #ZgotmplZ
+ Context {{.}} After
+ <a href="{{.}}"> #ZgotmplZ
since "O'Reilly:" is not an allowed protocol like "http:".
-
If {{.}} is the innocuous word, `left`, then it can appear more widely,
- Context {{.}} After
- {{.}} left
- <a title='{{.}}'> left
- <a href='{{.}}'> left
- <a href='/{{.}}'> left
- <a href='?dir={{.}}'> left
- <a style="border-{{.}}: 4px"> left
- <a style="align: {{.}}"> left
- <a style="background: '{{.}}'> left
- <a style="background: url('{{.}}')> left
- <style>p.{{.}} {color:red}</style> left
+ Context {{.}} After
+ {{.}} left
+ <a title='{{.}}'> left
+ <a href='{{.}}'> left
+ <a href='/{{.}}'> left
+ <a href='?dir={{.}}'> left
+ <a style="border-{{.}}: 4px"> left
+ <a style="align: {{.}}"> left
+ <a style="background: '{{.}}'> left
+ <a style="background: url('{{.}}')> left
+ <style>p.{{.}} {color:red}</style> left
Non-string values can be used in JavaScript contexts.
If {{.}} is
- struct{A,B string}{ "foo", "bar" }
+ struct{A,B string}{ "foo", "bar" }
in the escaped template
- <script>var pair = {{.}};</script>
+ <script>var pair = {{.}};</script>
then the template output is
- <script>var pair = {"A": "foo", "B": "bar"};</script>
+ <script>var pair = {"A": "foo", "B": "bar"};</script>
See package json to understand how non-string content is marshaled for
embedding in JavaScript contexts.
-
-Typed Strings
+# Typed Strings
By default, this package assumes that all pipelines produce a plain text string.
It adds escaping pipeline stages necessary to correctly and safely embed that
@@ -197,24 +192,23 @@ exempted from escaping.
The template
- Hello, {{.}}!
+ Hello, {{.}}!
can be invoked with
- tmpl.Execute(out, template.HTML(`<b>World</b>`))
+ tmpl.Execute(out, template.HTML(`<b>World</b>`))
to produce
- Hello, <b>World</b>!
+ Hello, <b>World</b>!
instead of the
- Hello, &lt;b&gt;World&lt;b&gt;!
+ Hello, &lt;b&gt;World&lt;b&gt;!
that would have been produced if {{.}} was a regular string.
-
-Security Model
+# Security Model
https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
diff --git a/src/html/template/error.go b/src/html/template/error.go
index 6bb5a2027f..5c51f772cb 100644
--- a/src/html/template/error.go
+++ b/src/html/template/error.go
@@ -32,14 +32,17 @@ type ErrorCode int
//
// Output: "ZgotmplZ"
// Example:
-// <img src="{{.X}}">
-// where {{.X}} evaluates to `javascript:...`
+//
+// <img src="{{.X}}">
+// where {{.X}} evaluates to `javascript:...`
+//
// Discussion:
-// "ZgotmplZ" is a special value that indicates that unsafe content reached a
-// CSS or URL context at runtime. The output of the example will be
-// <img src="#ZgotmplZ">
-// If the data comes from a trusted source, use content types to exempt it
-// from filtering: URL(`javascript:...`).
+//
+// "ZgotmplZ" is a special value that indicates that unsafe content reached a
+// CSS or URL context at runtime. The output of the example will be
+// <img src="#ZgotmplZ">
+// If the data comes from a trusted source, use content types to exempt it
+// from filtering: URL(`javascript:...`).
const (
// OK indicates the lack of an error.
OK ErrorCode = iota
diff --git a/src/html/template/escape.go b/src/html/template/escape.go
index 2b4027348a..54fbcdca33 100644
--- a/src/html/template/escape.go
+++ b/src/html/template/escape.go
@@ -411,13 +411,19 @@ func newIdentCmd(identifier string, pos parse.Pos) *parse.CommandNode {
// nudge returns the context that would result from following empty string
// transitions from the input context.
// For example, parsing:
-// `<a href=`
+//
+// `<a href=`
+//
// will end in context{stateBeforeValue, attrURL}, but parsing one extra rune:
-// `<a href=x`
+//
+// `<a href=x`
+//
// will end in context{stateURL, delimSpaceOrTagEnd, ...}.
// There are two transitions that happen when the 'x' is seen:
// (1) Transition from a before-value state to a start-of-value state without
-// consuming any character.
+//
+// consuming any character.
+//
// (2) Consume 'x' and transition past the first value character.
// In this case, nudging produces the context after (1) happens.
func nudge(c context) context {
diff --git a/src/html/template/html.go b/src/html/template/html.go
index 19bd0ccb20..46e9d93151 100644
--- a/src/html/template/html.go
+++ b/src/html/template/html.go
@@ -84,10 +84,12 @@ var htmlNormReplacementTable = []string{
// <script>(function () {
// var a = [], d = document.getElementById("d"), i, c, s;
// for (i = 0; i < 0x10000; ++i) {
-// c = String.fromCharCode(i);
-// d.innerHTML = "<span title=" + c + "lt" + c + "></span>"
-// s = d.getElementsByTagName("SPAN")[0];
-// if (!s || s.title !== c + "lt" + c) { a.push(i.toString(16)); }
+//
+// c = String.fromCharCode(i);
+// d.innerHTML = "<span title=" + c + "lt" + c + "></span>"
+// s = d.getElementsByTagName("SPAN")[0];
+// if (!s || s.title !== c + "lt" + c) { a.push(i.toString(16)); }
+//
// }
// document.write(a.join(", "));
// })()</script>
diff --git a/src/html/template/template.go b/src/html/template/template.go
index a99f69231c..30b64dff04 100644
--- a/src/html/template/template.go
+++ b/src/html/template/template.go
@@ -64,6 +64,7 @@ func (t *Template) Templates() []*Template {
//
// missingkey: Control the behavior during execution if a map is
// indexed with a key that is not present in the map.
+//
// "missingkey=default" or "missingkey=invalid"
// The default behavior: Do nothing and continue execution.
// If printed, the result of the index operation is the string
@@ -360,6 +361,7 @@ func (t *Template) Lookup(name string) *Template {
// Must is a helper that wraps a call to a function returning (*Template, error)
// and panics if the error is non-nil. It is intended for use in variable initializations
// such as
+//
// var t = template.Must(template.New("name").Parse("html"))
func Must(t *Template, err error) *Template {
if err != nil {
diff --git a/src/html/template/url.go b/src/html/template/url.go
index 93905586a2..9d0be39022 100644
--- a/src/html/template/url.go
+++ b/src/html/template/url.go
@@ -19,15 +19,15 @@ import (
//
// This filter conservatively assumes that all schemes other than the following
// are unsafe:
-// * http: Navigates to a new website, and may open a new window or tab.
-// These side effects can be reversed by navigating back to the
-// previous website, or closing the window or tab. No irreversible
-// changes will take place without further user interaction with
-// the new website.
-// * https: Same as http.
-// * mailto: Opens an email program and starts a new draft. This side effect
-// is not irreversible until the user explicitly clicks send; it
-// can be undone by closing the email program.
+// - http: Navigates to a new website, and may open a new window or tab.
+// These side effects can be reversed by navigating back to the
+// previous website, or closing the window or tab. No irreversible
+// changes will take place without further user interaction with
+// the new website.
+// - https: Same as http.
+// - mailto: Opens an email program and starts a new draft. This side effect
+// is not irreversible until the user explicitly clicks send; it
+// can be undone by closing the email program.
//
// To allow URLs containing other schemes to bypass this filter, developers must
// explicitly indicate that such a URL is expected and safe by encapsulating it