aboutsummaryrefslogtreecommitdiff
path: root/src/html
diff options
context:
space:
mode:
authorNodir Turakulov <nodir@google.com>2015-09-04 18:07:55 -0700
committerRob Pike <r@golang.org>2015-09-09 23:31:06 +0000
commit918c82308a8b489cc5f179f4e18531ad12cd6692 (patch)
tree566bcc4da2ad3ea3b08acdb3c91b29da8403be01 /src/html
parent6599450016244b9e3e074e87d7064219ee2e5cf8 (diff)
downloadgo-918c82308a8b489cc5f179f4e18531ad12cd6692.tar.xz
html/template: preserve attr in stateBeforeValue
Context: #12149. The problem there is that contents of <script type="text/template"> are treated as JS, and thus // is treated as regexp. Preserve context.attr while we are in the attribute, in particular in stateBeforeValue, so we have attr when reading attr value. Next CL will actually fix the bug. Change-Id: I99add2237b0885ecdcc08b4f7c25d0af99173e53 Reviewed-on: https://go-review.googlesource.com/14335 Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/html')
-rw-r--r--src/html/template/context.go3
-rw-r--r--src/html/template/escape_test.go124
-rw-r--r--src/html/template/transition.go2
3 files changed, 67 insertions, 62 deletions
diff --git a/src/html/template/context.go b/src/html/template/context.go
index 59e794d686..c90fc1fda5 100644
--- a/src/html/template/context.go
+++ b/src/html/template/context.go
@@ -310,7 +310,8 @@ func (e element) String() string {
return fmt.Sprintf("illegal element %d", int(e))
}
-// attr identifies the most recent HTML attribute when inside a start tag.
+// attr identifies the current HTML attribute when inside the attribute,
+// that is, starting from stateAttrName until stateTag/stateText (exclusive).
type attr uint8
const (
diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
index bea2d133c3..707394e3b0 100644
--- a/src/html/template/escape_test.go
+++ b/src/html/template/escape_test.go
@@ -1054,7 +1054,7 @@ func TestEscapeText(t *testing.T) {
},
{
`<a href=x`,
- context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href=x `,
@@ -1070,7 +1070,7 @@ func TestEscapeText(t *testing.T) {
},
{
`<a href ='`,
- context{state: stateURL, delim: delimSingleQuote},
+ context{state: stateURL, delim: delimSingleQuote, attr: attrURL},
},
{
`<a href=''`,
@@ -1078,7 +1078,7 @@ func TestEscapeText(t *testing.T) {
},
{
`<a href= "`,
- context{state: stateURL, delim: delimDoubleQuote},
+ context{state: stateURL, delim: delimDoubleQuote, attr: attrURL},
},
{
`<a href=""`,
@@ -1090,35 +1090,35 @@ func TestEscapeText(t *testing.T) {
},
{
`<a HREF='http:`,
- context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a Href='/`,
- context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href='"`,
- context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href="'`,
- context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href='&apos;`,
- context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href="&quot;`,
- context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href="&#34;`,
- context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<a href=&quot;`,
- context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery},
+ context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery, attr: attrURL},
},
{
`<img alt="1">`,
@@ -1138,83 +1138,83 @@ func TestEscapeText(t *testing.T) {
},
{
`<a onclick="`,
- context{state: stateJS, delim: delimDoubleQuote},
+ context{state: stateJS, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="//foo`,
- context{state: stateJSLineCmt, delim: delimDoubleQuote},
+ context{state: stateJSLineCmt, delim: delimDoubleQuote, attr: attrScript},
},
{
"<a onclick='//\n",
- context{state: stateJS, delim: delimSingleQuote},
+ context{state: stateJS, delim: delimSingleQuote, attr: attrScript},
},
{
"<a onclick='//\r\n",
- context{state: stateJS, delim: delimSingleQuote},
+ context{state: stateJS, delim: delimSingleQuote, attr: attrScript},
},
{
"<a onclick='//\u2028",
- context{state: stateJS, delim: delimSingleQuote},
+ context{state: stateJS, delim: delimSingleQuote, attr: attrScript},
},
{
`<a onclick="/*`,
- context{state: stateJSBlockCmt, delim: delimDoubleQuote},
+ context{state: stateJSBlockCmt, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="/*/`,
- context{state: stateJSBlockCmt, delim: delimDoubleQuote},
+ context{state: stateJSBlockCmt, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="/**/`,
- context{state: stateJS, delim: delimDoubleQuote},
+ context{state: stateJS, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onkeypress="&quot;`,
- context{state: stateJSDqStr, delim: delimDoubleQuote},
+ context{state: stateJSDqStr, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick='&quot;foo&quot;`,
- context{state: stateJS, delim: delimSingleQuote, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimSingleQuote, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<a onclick=&#39;foo&#39;`,
- context{state: stateJS, delim: delimSpaceOrTagEnd, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimSpaceOrTagEnd, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<a onclick=&#39;foo`,
- context{state: stateJSSqStr, delim: delimSpaceOrTagEnd},
+ context{state: stateJSSqStr, delim: delimSpaceOrTagEnd, attr: attrScript},
},
{
`<a onclick="&quot;foo'`,
- context{state: stateJSDqStr, delim: delimDoubleQuote},
+ context{state: stateJSDqStr, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="'foo&quot;`,
- context{state: stateJSSqStr, delim: delimDoubleQuote},
+ context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript},
},
{
`<A ONCLICK="'`,
- context{state: stateJSSqStr, delim: delimDoubleQuote},
+ context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="/`,
- context{state: stateJSRegexp, delim: delimDoubleQuote},
+ context{state: stateJSRegexp, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="'foo'`,
- context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<a onclick="'foo\'`,
- context{state: stateJSSqStr, delim: delimDoubleQuote},
+ context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="'foo\'`,
- context{state: stateJSSqStr, delim: delimDoubleQuote},
+ context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="/foo/`,
- context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<script>/foo/ /=`,
@@ -1222,111 +1222,111 @@ func TestEscapeText(t *testing.T) {
},
{
`<a onclick="1 /foo`,
- context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<a onclick="1 /*c*/ /foo`,
- context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<a onclick="/foo[/]`,
- context{state: stateJSRegexp, delim: delimDoubleQuote},
+ context{state: stateJSRegexp, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="/foo\/`,
- context{state: stateJSRegexp, delim: delimDoubleQuote},
+ context{state: stateJSRegexp, delim: delimDoubleQuote, attr: attrScript},
},
{
`<a onclick="/foo/`,
- context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+ context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp, attr: attrScript},
},
{
`<input checked style="`,
- context{state: stateCSS, delim: delimDoubleQuote},
+ context{state: stateCSS, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="//`,
- context{state: stateCSSLineCmt, delim: delimDoubleQuote},
+ context{state: stateCSSLineCmt, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="//</script>`,
- context{state: stateCSSLineCmt, delim: delimDoubleQuote},
+ context{state: stateCSSLineCmt, delim: delimDoubleQuote, attr: attrStyle},
},
{
"<a style='//\n",
- context{state: stateCSS, delim: delimSingleQuote},
+ context{state: stateCSS, delim: delimSingleQuote, attr: attrStyle},
},
{
"<a style='//\r",
- context{state: stateCSS, delim: delimSingleQuote},
+ context{state: stateCSS, delim: delimSingleQuote, attr: attrStyle},
},
{
`<a style="/*`,
- context{state: stateCSSBlockCmt, delim: delimDoubleQuote},
+ context{state: stateCSSBlockCmt, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="/*/`,
- context{state: stateCSSBlockCmt, delim: delimDoubleQuote},
+ context{state: stateCSSBlockCmt, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="/**/`,
- context{state: stateCSS, delim: delimDoubleQuote},
+ context{state: stateCSS, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="background: '`,
- context{state: stateCSSSqStr, delim: delimDoubleQuote},
+ context{state: stateCSSSqStr, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="background: &quot;`,
- context{state: stateCSSDqStr, delim: delimDoubleQuote},
+ context{state: stateCSSDqStr, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="background: '/foo?img=`,
- context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag},
+ context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag, attr: attrStyle},
},
{
`<a style="background: '/`,
- context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrStyle},
},
{
`<a style="background: url(&#x22;/`,
- context{state: stateCSSDqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateCSSDqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrStyle},
},
{
`<a style="background: url('/`,
- context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrStyle},
},
{
`<a style="background: url('/)`,
- context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrStyle},
},
{
`<a style="background: url('/ `,
- context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrStyle},
},
{
`<a style="background: url(/`,
- context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+ context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery, attr: attrStyle},
},
{
`<a style="background: url( `,
- context{state: stateCSSURL, delim: delimDoubleQuote},
+ context{state: stateCSSURL, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="background: url( /image?name=`,
- context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag},
+ context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag, attr: attrStyle},
},
{
`<a style="background: url(x)`,
- context{state: stateCSS, delim: delimDoubleQuote},
+ context{state: stateCSS, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="background: url('x'`,
- context{state: stateCSS, delim: delimDoubleQuote},
+ context{state: stateCSS, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<a style="background: url( x `,
- context{state: stateCSS, delim: delimDoubleQuote},
+ context{state: stateCSS, delim: delimDoubleQuote, attr: attrStyle},
},
{
`<!-- foo`,
@@ -1466,7 +1466,7 @@ func TestEscapeText(t *testing.T) {
},
{
`<a svg:style='`,
- context{state: stateCSS, delim: delimSingleQuote},
+ context{state: stateCSS, delim: delimSingleQuote, attr: attrStyle},
},
{
`<svg:font-face`,
@@ -1474,7 +1474,11 @@ func TestEscapeText(t *testing.T) {
},
{
`<svg:a svg:onclick="`,
- context{state: stateJS, delim: delimDoubleQuote},
+ context{state: stateJS, delim: delimDoubleQuote, attr: attrScript},
+ },
+ {
+ `<svg:a svg:onclick="x()">`,
+ context{},
},
}
diff --git a/src/html/template/transition.go b/src/html/template/transition.go
index d2e028741a..aefe0355af 100644
--- a/src/html/template/transition.go
+++ b/src/html/template/transition.go
@@ -169,7 +169,7 @@ func tBeforeValue(c context, s []byte) (context, int) {
case '"':
delim, i = delimDoubleQuote, i+1
}
- c.state, c.delim, c.attr = attrStartStates[c.attr], delim, attrNone
+ c.state, c.delim = attrStartStates[c.attr], delim
return c, i
}