|
2 | 2 | // Use of this source code is governed by a BSD-style |
3 | 3 | // license that can be found in the LICENSE file. |
4 | 4 |
|
5 | | -//go:build go1.13 && !windows |
6 | | -// +build go1.13,!windows |
| 5 | +//go:build !windows |
| 6 | +// +build !windows |
7 | 7 |
|
8 | 8 | package template |
9 | 9 |
|
@@ -236,6 +236,21 @@ func TestEscape(t *testing.T) { |
236 | 236 | "<script>alert({{.A}})</script>", |
237 | 237 | `<script>alert(["\u003ca\u003e","\u003cb\u003e"])</script>`, |
238 | 238 | }, |
| 239 | + { |
| 240 | + "scriptTypeSpace", |
| 241 | + "<script type=\" \">{{.H}}</script>", |
| 242 | + "<script type=\" \">\"\\u003cHello\\u003e\"</script>", |
| 243 | + }, |
| 244 | + { |
| 245 | + "scriptTypeTab", |
| 246 | + "<script type=\"\t\">{{.H}}</script>", |
| 247 | + "<script type=\"\t\">\"\\u003cHello\\u003e\"</script>", |
| 248 | + }, |
| 249 | + { |
| 250 | + "scriptTypeEmpty", |
| 251 | + "<script type=\"\">{{.H}}</script>", |
| 252 | + "<script type=\"\">\"\\u003cHello\\u003e\"</script>", |
| 253 | + }, |
239 | 254 | { |
240 | 255 | "jsObjValueNotOverEscaped", |
241 | 256 | "<button onclick='alert({{.A | html}})'>", |
@@ -749,6 +764,26 @@ func TestEscape(t *testing.T) { |
749 | 764 | `<meta http-equiv="refresh" content="{{"asd: 123"}}">`, |
750 | 765 | `<meta http-equiv="refresh" content="asd: 123">`, |
751 | 766 | }, |
| 767 | + { |
| 768 | + "meta content url with whitespace before equals", |
| 769 | + `<meta http-equiv="refresh" content="0;url ={{"javascript:alert(1)"}}">`, |
| 770 | + `<meta http-equiv="refresh" content="0;url =#ZgotmplZ">`, |
| 771 | + }, |
| 772 | + { |
| 773 | + "meta content url with tab before equals", |
| 774 | + "<meta http-equiv=\"refresh\" content=\"0;url\t={{\"javascript:alert(1)\"}}\">", |
| 775 | + "<meta http-equiv=\"refresh\" content=\"0;url\t=#ZgotmplZ\">", |
| 776 | + }, |
| 777 | + { |
| 778 | + "meta content url with space after equals", |
| 779 | + `<meta http-equiv="refresh" content="0;url= {{"javascript:alert(1)"}}">`, |
| 780 | + `<meta http-equiv="refresh" content="0;url= #ZgotmplZ">`, |
| 781 | + }, |
| 782 | + { |
| 783 | + "meta content url with whitespace both sides of equals", |
| 784 | + "<meta http-equiv=\"refresh\" content=\"0;url \t= {{\"javascript:alert(1)\"}}\">", |
| 785 | + "<meta http-equiv=\"refresh\" content=\"0;url \t= #ZgotmplZ\">", |
| 786 | + }, |
752 | 787 | } |
753 | 788 |
|
754 | 789 | for _, test := range tests { |
@@ -1189,6 +1224,18 @@ func TestErrors(t *testing.T) { |
1189 | 1224 | // html is allowed since it is the last command in the pipeline, but urlquery is not. |
1190 | 1225 | `predefined escaper "urlquery" disallowed in template`, |
1191 | 1226 | }, |
| 1227 | + { |
| 1228 | + "<script>var a = `{{if .X}}`{{end}}", |
| 1229 | + `{{if}} branches end in different contexts`, |
| 1230 | + }, |
| 1231 | + { |
| 1232 | + "<script>var a = `{{if .X}}a{{else}}`{{end}}", |
| 1233 | + `{{if}} branches end in different contexts`, |
| 1234 | + }, |
| 1235 | + { |
| 1236 | + "<script>var a = `{{if .X}}a{{else}}b{{end}}`</script>", |
| 1237 | + ``, |
| 1238 | + }, |
1192 | 1239 | } |
1193 | 1240 | for _, test := range tests { |
1194 | 1241 | buf := new(bytes.Buffer) |
@@ -1759,43 +1806,43 @@ func TestEscapeText(t *testing.T) { |
1759 | 1806 | }, |
1760 | 1807 | { |
1761 | 1808 | "<script>var a = `${", |
1762 | | - context{state: stateJS, element: elementScript}, |
| 1809 | + context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}}, |
1763 | 1810 | }, |
1764 | 1811 | { |
1765 | 1812 | "<script>var a = `${}", |
1766 | 1813 | context{state: stateJSTmplLit, element: elementScript}, |
1767 | 1814 | }, |
1768 | 1815 | { |
1769 | 1816 | "<script>var a = `${`", |
1770 | | - context{state: stateJSTmplLit, element: elementScript}, |
| 1817 | + context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, |
1771 | 1818 | }, |
1772 | 1819 | { |
1773 | 1820 | "<script>var a = `${var a = \"", |
1774 | | - context{state: stateJSDqStr, element: elementScript}, |
| 1821 | + context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, |
1775 | 1822 | }, |
1776 | 1823 | { |
1777 | 1824 | "<script>var a = `${var a = \"`", |
1778 | | - context{state: stateJSDqStr, element: elementScript}, |
| 1825 | + context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, |
1779 | 1826 | }, |
1780 | 1827 | { |
1781 | 1828 | "<script>var a = `${var a = \"}", |
1782 | | - context{state: stateJSDqStr, element: elementScript}, |
| 1829 | + context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, |
1783 | 1830 | }, |
1784 | 1831 | { |
1785 | 1832 | "<script>var a = `${``", |
1786 | | - context{state: stateJS, element: elementScript}, |
| 1833 | + context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}}, |
1787 | 1834 | }, |
1788 | 1835 | { |
1789 | 1836 | "<script>var a = `${`}", |
1790 | | - context{state: stateJSTmplLit, element: elementScript}, |
| 1837 | + context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, |
1791 | 1838 | }, |
1792 | 1839 | { |
1793 | 1840 | "<script>`${ {} } asd`</script><script>`${ {} }", |
1794 | 1841 | context{state: stateJSTmplLit, element: elementScript}, |
1795 | 1842 | }, |
1796 | 1843 | { |
1797 | 1844 | "<script>var foo = `${ (_ => { return \"x\" })() + \"${", |
1798 | | - context{state: stateJSDqStr, element: elementScript}, |
| 1845 | + context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, |
1799 | 1846 | }, |
1800 | 1847 | { |
1801 | 1848 | "<script>var a = `${ {</script><script>var b = `${ x }", |
@@ -1823,23 +1870,23 @@ func TestEscapeText(t *testing.T) { |
1823 | 1870 | }, |
1824 | 1871 | { |
1825 | 1872 | "<script>`${ { `` }", |
1826 | | - context{state: stateJS, element: elementScript}, |
| 1873 | + context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}}, |
1827 | 1874 | }, |
1828 | 1875 | { |
1829 | 1876 | "<script>`${ { }`", |
1830 | | - context{state: stateJSTmplLit, element: elementScript}, |
| 1877 | + context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, |
1831 | 1878 | }, |
1832 | 1879 | { |
1833 | 1880 | "<script>var foo = `${ foo({ a: { c: `${", |
1834 | | - context{state: stateJS, element: elementScript}, |
| 1881 | + context{state: stateJS, element: elementScript, jsBraceDepth: []int{2, 0}}, |
1835 | 1882 | }, |
1836 | 1883 | { |
1837 | 1884 | "<script>var foo = `${ foo({ a: { c: `${ {{.}} }` }, b: ", |
1838 | | - context{state: stateJS, element: elementScript}, |
| 1885 | + context{state: stateJS, element: elementScript, jsBraceDepth: []int{1}}, |
1839 | 1886 | }, |
1840 | 1887 | { |
1841 | 1888 | "<script>`${ `}", |
1842 | | - context{state: stateJSTmplLit, element: elementScript}, |
| 1889 | + context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, |
1843 | 1890 | }, |
1844 | 1891 | } |
1845 | 1892 |
|
|
0 commit comments