summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/go
diff options
context:
space:
mode:
authorShubham Kulkarni <skulkarni@mvista.com>2023-10-03 23:28:51 +0530
committerSteve Sakoman <steve@sakoman.com>2023-10-13 05:47:07 -1000
commit43ffc2a5e70f8936742b632263d06f1f63e326fb (patch)
tree67c097a7aca6cc0c093f419a099fe94b1970374c /meta/recipes-devtools/go
parenta9d6f0c153acf62ff7eae3141e337194e2429e09 (diff)
downloadpoky-43ffc2a5e70f8936742b632263d06f1f63e326fb.tar.gz
go: Update fix for CVE-2023-24538 & CVE-2023-39318
Add missing files in fix for CVE-2023-24538 & CVE-2023-39318 Upstream Link - CVE-2023-24538: https://github.com/golang/go/commit/b1e3ecfa06b67014429a197ec5e134ce4303ad9b CVE-2023-39318: https://github.com/golang/go/commit/023b542edf38e2a1f87fcefb9f75ff2f99401b4c (From OE-Core rev: cc6f7a8e8805058aababb65e10da7ed2e3d77461) Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta/recipes-devtools/go')
-rw-r--r--meta/recipes-devtools/go/go-1.14.inc5
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538-1.patch4
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538-2.patch447
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch393
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch497
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538_5.patch585
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538_6.patch (renamed from meta/recipes-devtools/go/go-1.14/CVE-2023-24538-3.patch)175
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-39318.patch38
8 files changed, 2124 insertions, 20 deletions
diff --git a/meta/recipes-devtools/go/go-1.14.inc b/meta/recipes-devtools/go/go-1.14.inc
index be63f64825..091b778de8 100644
--- a/meta/recipes-devtools/go/go-1.14.inc
+++ b/meta/recipes-devtools/go/go-1.14.inc
@@ -60,7 +60,10 @@ SRC_URI += "\
60 file://CVE-2023-24534.patch \ 60 file://CVE-2023-24534.patch \
61 file://CVE-2023-24538-1.patch \ 61 file://CVE-2023-24538-1.patch \
62 file://CVE-2023-24538-2.patch \ 62 file://CVE-2023-24538-2.patch \
63 file://CVE-2023-24538-3.patch \ 63 file://CVE-2023-24538_3.patch \
64 file://CVE-2023-24538_4.patch \
65 file://CVE-2023-24538_5.patch \
66 file://CVE-2023-24538_6.patch \
64 file://CVE-2023-24539.patch \ 67 file://CVE-2023-24539.patch \
65 file://CVE-2023-24540.patch \ 68 file://CVE-2023-24540.patch \
66 file://CVE-2023-29405-1.patch \ 69 file://CVE-2023-29405-1.patch \
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-1.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-1.patch
index eda26e5ff6..23c5075e41 100644
--- a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-1.patch
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-1.patch
@@ -1,7 +1,7 @@
1From 8acd01094d9ee17f6e763a61e49a8a808b3a9ddb Mon Sep 17 00:00:00 2001 1From 8acd01094d9ee17f6e763a61e49a8a808b3a9ddb Mon Sep 17 00:00:00 2001
2From: Brad Fitzpatrick <bradfitz@golang.org> 2From: Brad Fitzpatrick <bradfitz@golang.org>
3Date: Mon, 2 Aug 2021 14:55:51 -0700 3Date: Mon, 2 Aug 2021 14:55:51 -0700
4Subject: [PATCH 1/3] net/netip: add new IP address package 4Subject: [PATCH 1/6] net/netip: add new IP address package
5 5
6Co-authored-by: Alex Willmer <alex@moreati.org.uk> (GitHub @moreati) 6Co-authored-by: Alex Willmer <alex@moreati.org.uk> (GitHub @moreati)
7Co-authored-by: Alexander Yastrebov <yastrebov.alex@gmail.com> 7Co-authored-by: Alexander Yastrebov <yastrebov.alex@gmail.com>
@@ -31,7 +31,7 @@ Trust: Brad Fitzpatrick <bradfitz@golang.org>
31 31
32Dependency Patch #1 32Dependency Patch #1
33 33
34Upstream-Status: Backport [https://github.com/golang/go/commit/a59e33224e42d60a97fa720a45e1b74eb6aaa3d0] 34Upstream-Status: Backport from https://github.com/golang/go/commit/a59e33224e42d60a97fa720a45e1b74eb6aaa3d0
35CVE: CVE-2023-24538 35CVE: CVE-2023-24538
36Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> 36Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
37--- 37---
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-2.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-2.patch
index 5036f2890b..f200c41e16 100644
--- a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-2.patch
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-2.patch
@@ -1,7 +1,7 @@
1From 6fc21505614f36178df0dad7034b6b8e3f7588d5 Mon Sep 17 00:00:00 2001 1From 6fc21505614f36178df0dad7034b6b8e3f7588d5 Mon Sep 17 00:00:00 2001
2From: empijei <robclap8@gmail.com> 2From: empijei <robclap8@gmail.com>
3Date: Fri, 27 Mar 2020 19:27:55 +0100 3Date: Fri, 27 Mar 2020 19:27:55 +0100
4Subject: [PATCH 2/3] html/template,text/template: switch to Unicode escapes 4Subject: [PATCH 2/6] html/template,text/template: switch to Unicode escapes
5 for JSON compatibility 5 for JSON compatibility
6MIME-Version: 1.0 6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8 7Content-Type: text/plain; charset=UTF-8
@@ -31,10 +31,238 @@ Upstream-Status: Backport from https://github.com/golang/go/commit/d4d298040d072
31CVE: CVE-2023-24538 31CVE: CVE-2023-24538
32Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> 32Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
33--- 33---
34 src/html/template/js.go | 70 +++++++++++++++++++++++++++------------------- 34 src/html/template/content_test.go | 70 +++++++++++++++++++-------------------
35 src/text/template/funcs.go | 8 +++--- 35 src/html/template/escape_test.go | 6 ++--
36 2 files changed, 46 insertions(+), 32 deletions(-) 36 src/html/template/example_test.go | 6 ++--
37 src/html/template/js.go | 70 +++++++++++++++++++++++---------------
38 src/html/template/js_test.go | 68 ++++++++++++++++++------------------
39 src/html/template/template_test.go | 39 +++++++++++++++++++++
40 src/text/template/exec_test.go | 6 ++--
41 src/text/template/funcs.go | 8 ++---
42 8 files changed, 163 insertions(+), 110 deletions(-)
37 43
44diff --git a/src/html/template/content_test.go b/src/html/template/content_test.go
45index 72d56f5..bd86527 100644
46--- a/src/html/template/content_test.go
47+++ b/src/html/template/content_test.go
48@@ -18,7 +18,7 @@ func TestTypedContent(t *testing.T) {
49 HTML(`Hello, <b>World</b> &amp;tc!`),
50 HTMLAttr(` dir="ltr"`),
51 JS(`c && alert("Hello, World!");`),
52- JSStr(`Hello, World & O'Reilly\x21`),
53+ JSStr(`Hello, World & O'Reilly\u0021`),
54 URL(`greeting=H%69,&addressee=(World)`),
55 Srcset(`greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`),
56 URL(`,foo/,`),
57@@ -70,7 +70,7 @@ func TestTypedContent(t *testing.T) {
58 `Hello, <b>World</b> &amp;tc!`,
59 ` dir=&#34;ltr&#34;`,
60 `c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
61- `Hello, World &amp; O&#39;Reilly\x21`,
62+ `Hello, World &amp; O&#39;Reilly\u0021`,
63 `greeting=H%69,&amp;addressee=(World)`,
64 `greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
65 `,foo/,`,
66@@ -100,7 +100,7 @@ func TestTypedContent(t *testing.T) {
67 `Hello,&#32;World&#32;&amp;tc!`,
68 `&#32;dir&#61;&#34;ltr&#34;`,
69 `c&#32;&amp;&amp;&#32;alert(&#34;Hello,&#32;World!&#34;);`,
70- `Hello,&#32;World&#32;&amp;&#32;O&#39;Reilly\x21`,
71+ `Hello,&#32;World&#32;&amp;&#32;O&#39;Reilly\u0021`,
72 `greeting&#61;H%69,&amp;addressee&#61;(World)`,
73 `greeting&#61;H%69,&amp;addressee&#61;(World)&#32;2x,&#32;https://golang.org/favicon.ico&#32;500.5w`,
74 `,foo/,`,
75@@ -115,7 +115,7 @@ func TestTypedContent(t *testing.T) {
76 `Hello, World &amp;tc!`,
77 ` dir=&#34;ltr&#34;`,
78 `c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
79- `Hello, World &amp; O&#39;Reilly\x21`,
80+ `Hello, World &amp; O&#39;Reilly\u0021`,
81 `greeting=H%69,&amp;addressee=(World)`,
82 `greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
83 `,foo/,`,
84@@ -130,7 +130,7 @@ func TestTypedContent(t *testing.T) {
85 `Hello, &lt;b&gt;World&lt;/b&gt; &amp;tc!`,
86 ` dir=&#34;ltr&#34;`,
87 `c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
88- `Hello, World &amp; O&#39;Reilly\x21`,
89+ `Hello, World &amp; O&#39;Reilly\u0021`,
90 `greeting=H%69,&amp;addressee=(World)`,
91 `greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
92 `,foo/,`,
93@@ -146,7 +146,7 @@ func TestTypedContent(t *testing.T) {
94 // Not escaped.
95 `c && alert("Hello, World!");`,
96 // Escape sequence not over-escaped.
97- `"Hello, World & O'Reilly\x21"`,
98+ `"Hello, World & O'Reilly\u0021"`,
99 `"greeting=H%69,\u0026addressee=(World)"`,
100 `"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`,
101 `",foo/,"`,
102@@ -162,7 +162,7 @@ func TestTypedContent(t *testing.T) {
103 // Not JS escaped but HTML escaped.
104 `c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
105 // Escape sequence not over-escaped.
106- `&#34;Hello, World &amp; O&#39;Reilly\x21&#34;`,
107+ `&#34;Hello, World &amp; O&#39;Reilly\u0021&#34;`,
108 `&#34;greeting=H%69,\u0026addressee=(World)&#34;`,
109 `&#34;greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w&#34;`,
110 `&#34;,foo/,&#34;`,
111@@ -171,30 +171,30 @@ func TestTypedContent(t *testing.T) {
112 {
113 `<script>alert("{{.}}")</script>`,
114 []string{
115- `\x3cb\x3e \x22foo%\x22 O\x27Reilly \x26bar;`,
116- `a[href =~ \x22\/\/example.com\x22]#foo`,
117- `Hello, \x3cb\x3eWorld\x3c\/b\x3e \x26amp;tc!`,
118- ` dir=\x22ltr\x22`,
119- `c \x26\x26 alert(\x22Hello, World!\x22);`,
120+ `\u003cb\u003e \u0022foo%\u0022 O\u0027Reilly \u0026bar;`,
121+ `a[href =~ \u0022\/\/example.com\u0022]#foo`,
122+ `Hello, \u003cb\u003eWorld\u003c\/b\u003e \u0026amp;tc!`,
123+ ` dir=\u0022ltr\u0022`,
124+ `c \u0026\u0026 alert(\u0022Hello, World!\u0022);`,
125 // Escape sequence not over-escaped.
126- `Hello, World \x26 O\x27Reilly\x21`,
127- `greeting=H%69,\x26addressee=(World)`,
128- `greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
129+ `Hello, World \u0026 O\u0027Reilly\u0021`,
130+ `greeting=H%69,\u0026addressee=(World)`,
131+ `greeting=H%69,\u0026addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
132 `,foo\/,`,
133 },
134 },
135 {
136 `<script type="text/javascript">alert("{{.}}")</script>`,
137 []string{
138- `\x3cb\x3e \x22foo%\x22 O\x27Reilly \x26bar;`,
139- `a[href =~ \x22\/\/example.com\x22]#foo`,
140- `Hello, \x3cb\x3eWorld\x3c\/b\x3e \x26amp;tc!`,
141- ` dir=\x22ltr\x22`,
142- `c \x26\x26 alert(\x22Hello, World!\x22);`,
143+ `\u003cb\u003e \u0022foo%\u0022 O\u0027Reilly \u0026bar;`,
144+ `a[href =~ \u0022\/\/example.com\u0022]#foo`,
145+ `Hello, \u003cb\u003eWorld\u003c\/b\u003e \u0026amp;tc!`,
146+ ` dir=\u0022ltr\u0022`,
147+ `c \u0026\u0026 alert(\u0022Hello, World!\u0022);`,
148 // Escape sequence not over-escaped.
149- `Hello, World \x26 O\x27Reilly\x21`,
150- `greeting=H%69,\x26addressee=(World)`,
151- `greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
152+ `Hello, World \u0026 O\u0027Reilly\u0021`,
153+ `greeting=H%69,\u0026addressee=(World)`,
154+ `greeting=H%69,\u0026addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
155 `,foo\/,`,
156 },
157 },
158@@ -208,7 +208,7 @@ func TestTypedContent(t *testing.T) {
159 // Not escaped.
160 `c && alert("Hello, World!");`,
161 // Escape sequence not over-escaped.
162- `"Hello, World & O'Reilly\x21"`,
163+ `"Hello, World & O'Reilly\u0021"`,
164 `"greeting=H%69,\u0026addressee=(World)"`,
165 `"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`,
166 `",foo/,"`,
167@@ -224,7 +224,7 @@ func TestTypedContent(t *testing.T) {
168 `Hello, <b>World</b> &amp;tc!`,
169 ` dir=&#34;ltr&#34;`,
170 `c &amp;&amp; alert(&#34;Hello, World!&#34;);`,
171- `Hello, World &amp; O&#39;Reilly\x21`,
172+ `Hello, World &amp; O&#39;Reilly\u0021`,
173 `greeting=H%69,&amp;addressee=(World)`,
174 `greeting=H%69,&amp;addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`,
175 `,foo/,`,
176@@ -233,15 +233,15 @@ func TestTypedContent(t *testing.T) {
177 {
178 `<button onclick='alert("{{.}}")'>`,
179 []string{
180- `\x3cb\x3e \x22foo%\x22 O\x27Reilly \x26bar;`,
181- `a[href =~ \x22\/\/example.com\x22]#foo`,
182- `Hello, \x3cb\x3eWorld\x3c\/b\x3e \x26amp;tc!`,
183- ` dir=\x22ltr\x22`,
184- `c \x26\x26 alert(\x22Hello, World!\x22);`,
185+ `\u003cb\u003e \u0022foo%\u0022 O\u0027Reilly \u0026bar;`,
186+ `a[href =~ \u0022\/\/example.com\u0022]#foo`,
187+ `Hello, \u003cb\u003eWorld\u003c\/b\u003e \u0026amp;tc!`,
188+ ` dir=\u0022ltr\u0022`,
189+ `c \u0026\u0026 alert(\u0022Hello, World!\u0022);`,
190 // Escape sequence not over-escaped.
191- `Hello, World \x26 O\x27Reilly\x21`,
192- `greeting=H%69,\x26addressee=(World)`,
193- `greeting=H%69,\x26addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
194+ `Hello, World \u0026 O\u0027Reilly\u0021`,
195+ `greeting=H%69,\u0026addressee=(World)`,
196+ `greeting=H%69,\u0026addressee=(World) 2x, https:\/\/golang.org\/favicon.ico 500.5w`,
197 `,foo\/,`,
198 },
199 },
200@@ -253,7 +253,7 @@ func TestTypedContent(t *testing.T) {
201 `Hello%2c%20%3cb%3eWorld%3c%2fb%3e%20%26amp%3btc%21`,
202 `%20dir%3d%22ltr%22`,
203 `c%20%26%26%20alert%28%22Hello%2c%20World%21%22%29%3b`,
204- `Hello%2c%20World%20%26%20O%27Reilly%5cx21`,
205+ `Hello%2c%20World%20%26%20O%27Reilly%5cu0021`,
206 // Quotes and parens are escaped but %69 is not over-escaped. HTML escaping is done.
207 `greeting=H%69,&amp;addressee=%28World%29`,
208 `greeting%3dH%2569%2c%26addressee%3d%28World%29%202x%2c%20https%3a%2f%2fgolang.org%2ffavicon.ico%20500.5w`,
209@@ -268,7 +268,7 @@ func TestTypedContent(t *testing.T) {
210 `Hello%2c%20%3cb%3eWorld%3c%2fb%3e%20%26amp%3btc%21`,
211 `%20dir%3d%22ltr%22`,
212 `c%20%26%26%20alert%28%22Hello%2c%20World%21%22%29%3b`,
213- `Hello%2c%20World%20%26%20O%27Reilly%5cx21`,
214+ `Hello%2c%20World%20%26%20O%27Reilly%5cu0021`,
215 // Quotes and parens are escaped but %69 is not over-escaped. HTML escaping is not done.
216 `greeting=H%69,&addressee=%28World%29`,
217 `greeting%3dH%2569%2c%26addressee%3d%28World%29%202x%2c%20https%3a%2f%2fgolang.org%2ffavicon.ico%20500.5w`,
218diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
219index e72a9ba..c709660 100644
220--- a/src/html/template/escape_test.go
221+++ b/src/html/template/escape_test.go
222@@ -238,7 +238,7 @@ func TestEscape(t *testing.T) {
223 {
224 "jsStr",
225 "<button onclick='alert(&quot;{{.H}}&quot;)'>",
226- `<button onclick='alert(&quot;\x3cHello\x3e&quot;)'>`,
227+ `<button onclick='alert(&quot;\u003cHello\u003e&quot;)'>`,
228 },
229 {
230 "badMarshaler",
231@@ -259,7 +259,7 @@ func TestEscape(t *testing.T) {
232 {
233 "jsRe",
234 `<button onclick='alert(/{{"foo+bar"}}/.test(""))'>`,
235- `<button onclick='alert(/foo\x2bbar/.test(""))'>`,
236+ `<button onclick='alert(/foo\u002bbar/.test(""))'>`,
237 },
238 {
239 "jsReBlank",
240@@ -825,7 +825,7 @@ func TestEscapeSet(t *testing.T) {
241 "main": `<button onclick="title='{{template "helper"}}'; ...">{{template "helper"}}</button>`,
242 "helper": `{{11}} of {{"<100>"}}`,
243 },
244- `<button onclick="title='11 of \x3c100\x3e'; ...">11 of &lt;100&gt;</button>`,
245+ `<button onclick="title='11 of \u003c100\u003e'; ...">11 of &lt;100&gt;</button>`,
246 },
247 // A non-recursive template that ends in a different context.
248 // helper starts in jsCtxRegexp and ends in jsCtxDivOp.
249diff --git a/src/html/template/example_test.go b/src/html/template/example_test.go
250index 9d965f1..6cf936f 100644
251--- a/src/html/template/example_test.go
252+++ b/src/html/template/example_test.go
253@@ -116,9 +116,9 @@ func Example_escape() {
254 // &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;tasty@example.com&gt;
255 // &#34;Fran &amp; Freddie&#39;s Diner&#34; &lt;tasty@example.com&gt;
256 // &#34;Fran &amp; Freddie&#39;s Diner&#34;32&lt;tasty@example.com&gt;
257- // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E
258- // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E
259- // \"Fran \x26 Freddie\'s Diner\"32\x3Ctasty@example.com\x3E
260+ // \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E
261+ // \"Fran \u0026 Freddie\'s Diner\" \u003Ctasty@example.com\u003E
262+ // \"Fran \u0026 Freddie\'s Diner\"32\u003Ctasty@example.com\u003E
263 // %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E
264
265 }
38diff --git a/src/html/template/js.go b/src/html/template/js.go 266diff --git a/src/html/template/js.go b/src/html/template/js.go
39index 0e91458..ea9c183 100644 267index 0e91458..ea9c183 100644
40--- a/src/html/template/js.go 268--- a/src/html/template/js.go
@@ -173,6 +401,217 @@ index 0e91458..ea9c183 100644
173 '?': `\?`, 401 '?': `\?`,
174 '[': `\[`, 402 '[': `\[`,
175 '\\': `\\`, 403 '\\': `\\`,
404diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go
405index 075adaa..d7ee47b 100644
406--- a/src/html/template/js_test.go
407+++ b/src/html/template/js_test.go
408@@ -137,7 +137,7 @@ func TestJSValEscaper(t *testing.T) {
409 {"foo", `"foo"`},
410 // Newlines.
411 {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`},
412- // "\v" == "v" on IE 6 so use "\x0b" instead.
413+ // "\v" == "v" on IE 6 so use "\u000b" instead.
414 {"\t\x0b", `"\t\u000b"`},
415 {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`},
416 {[]interface{}{}, "[]"},
417@@ -173,7 +173,7 @@ func TestJSStrEscaper(t *testing.T) {
418 }{
419 {"", ``},
420 {"foo", `foo`},
421- {"\u0000", `\0`},
422+ {"\u0000", `\u0000`},
423 {"\t", `\t`},
424 {"\n", `\n`},
425 {"\r", `\r`},
426@@ -183,14 +183,14 @@ func TestJSStrEscaper(t *testing.T) {
427 {"\\n", `\\n`},
428 {"foo\r\nbar", `foo\r\nbar`},
429 // Preserve attribute boundaries.
430- {`"`, `\x22`},
431- {`'`, `\x27`},
432+ {`"`, `\u0022`},
433+ {`'`, `\u0027`},
434 // Allow embedding in HTML without further escaping.
435- {`&amp;`, `\x26amp;`},
436+ {`&amp;`, `\u0026amp;`},
437 // Prevent breaking out of text node and element boundaries.
438- {"</script>", `\x3c\/script\x3e`},
439- {"<![CDATA[", `\x3c![CDATA[`},
440- {"]]>", `]]\x3e`},
441+ {"</script>", `\u003c\/script\u003e`},
442+ {"<![CDATA[", `\u003c![CDATA[`},
443+ {"]]>", `]]\u003e`},
444 // https://dev.w3.org/html5/markup/aria/syntax.html#escaping-text-span
445 // "The text in style, script, title, and textarea elements
446 // must not have an escaping text span start that is not
447@@ -201,11 +201,11 @@ func TestJSStrEscaper(t *testing.T) {
448 // allow regular text content to be interpreted as script
449 // allowing script execution via a combination of a JS string
450 // injection followed by an HTML text injection.
451- {"<!--", `\x3c!--`},
452- {"-->", `--\x3e`},
453+ {"<!--", `\u003c!--`},
454+ {"-->", `--\u003e`},
455 // From https://code.google.com/p/doctype/wiki/ArticleUtf7
456 {"+ADw-script+AD4-alert(1)+ADw-/script+AD4-",
457- `\x2bADw-script\x2bAD4-alert(1)\x2bADw-\/script\x2bAD4-`,
458+ `\u002bADw-script\u002bAD4-alert(1)\u002bADw-\/script\u002bAD4-`,
459 },
460 // Invalid UTF-8 sequence
461 {"foo\xA0bar", "foo\xA0bar"},
462@@ -228,7 +228,7 @@ func TestJSRegexpEscaper(t *testing.T) {
463 }{
464 {"", `(?:)`},
465 {"foo", `foo`},
466- {"\u0000", `\0`},
467+ {"\u0000", `\u0000`},
468 {"\t", `\t`},
469 {"\n", `\n`},
470 {"\r", `\r`},
471@@ -238,19 +238,19 @@ func TestJSRegexpEscaper(t *testing.T) {
472 {"\\n", `\\n`},
473 {"foo\r\nbar", `foo\r\nbar`},
474 // Preserve attribute boundaries.
475- {`"`, `\x22`},
476- {`'`, `\x27`},
477+ {`"`, `\u0022`},
478+ {`'`, `\u0027`},
479 // Allow embedding in HTML without further escaping.
480- {`&amp;`, `\x26amp;`},
481+ {`&amp;`, `\u0026amp;`},
482 // Prevent breaking out of text node and element boundaries.
483- {"</script>", `\x3c\/script\x3e`},
484- {"<![CDATA[", `\x3c!\[CDATA\[`},
485- {"]]>", `\]\]\x3e`},
486+ {"</script>", `\u003c\/script\u003e`},
487+ {"<![CDATA[", `\u003c!\[CDATA\[`},
488+ {"]]>", `\]\]\u003e`},
489 // Escaping text spans.
490- {"<!--", `\x3c!\-\-`},
491- {"-->", `\-\-\x3e`},
492+ {"<!--", `\u003c!\-\-`},
493+ {"-->", `\-\-\u003e`},
494 {"*", `\*`},
495- {"+", `\x2b`},
496+ {"+", `\u002b`},
497 {"?", `\?`},
498 {"[](){}", `\[\]\(\)\{\}`},
499 {"$foo|x.y", `\$foo\|x\.y`},
500@@ -284,27 +284,27 @@ func TestEscapersOnLower7AndSelectHighCodepoints(t *testing.T) {
501 {
502 "jsStrEscaper",
503 jsStrEscaper,
504- "\\0\x01\x02\x03\x04\x05\x06\x07" +
505- "\x08\\t\\n\\x0b\\f\\r\x0E\x0F" +
506- "\x10\x11\x12\x13\x14\x15\x16\x17" +
507- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
508- ` !\x22#$%\x26\x27()*\x2b,-.\/` +
509- `0123456789:;\x3c=\x3e?` +
510+ `\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007` +
511+ `\u0008\t\n\u000b\f\r\u000e\u000f` +
512+ `\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017` +
513+ `\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f` +
514+ ` !\u0022#$%\u0026\u0027()*\u002b,-.\/` +
515+ `0123456789:;\u003c=\u003e?` +
516 `@ABCDEFGHIJKLMNO` +
517 `PQRSTUVWXYZ[\\]^_` +
518 "`abcdefghijklmno" +
519- "pqrstuvwxyz{|}~\x7f" +
520+ "pqrstuvwxyz{|}~\u007f" +
521 "\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E",
522 },
523 {
524 "jsRegexpEscaper",
525 jsRegexpEscaper,
526- "\\0\x01\x02\x03\x04\x05\x06\x07" +
527- "\x08\\t\\n\\x0b\\f\\r\x0E\x0F" +
528- "\x10\x11\x12\x13\x14\x15\x16\x17" +
529- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
530- ` !\x22#\$%\x26\x27\(\)\*\x2b,\-\.\/` +
531- `0123456789:;\x3c=\x3e\?` +
532+ `\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007` +
533+ `\u0008\t\n\u000b\f\r\u000e\u000f` +
534+ `\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017` +
535+ `\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f` +
536+ ` !\u0022#\$%\u0026\u0027\(\)\*\u002b,\-\.\/` +
537+ `0123456789:;\u003c=\u003e\?` +
538 `@ABCDEFGHIJKLMNO` +
539 `PQRSTUVWXYZ\[\\\]\^_` +
540 "`abcdefghijklmno" +
541diff --git a/src/html/template/template_test.go b/src/html/template/template_test.go
542index 13e6ba4..86bd4db 100644
543--- a/src/html/template/template_test.go
544+++ b/src/html/template/template_test.go
545@@ -6,6 +6,7 @@ package template_test
546
547 import (
548 "bytes"
549+ "encoding/json"
550 . "html/template"
551 "strings"
552 "testing"
553@@ -121,6 +122,44 @@ func TestNumbers(t *testing.T) {
554 c.mustExecute(c.root, nil, "12.34 7.5")
555 }
556
557+func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) {
558+ // See #33671 and #37634 for more context on this.
559+ tests := []struct{ name, in string }{
560+ {"empty", ""},
561+ {"invalid", string(rune(-1))},
562+ {"null", "\u0000"},
563+ {"unit separator", "\u001F"},
564+ {"tab", "\t"},
565+ {"gt and lt", "<>"},
566+ {"quotes", `'"`},
567+ {"ASCII letters", "ASCII letters"},
568+ {"Unicode", "ʕ⊙ϖ⊙ʔ"},
569+ {"Pizza", "P"},
570+ }
571+ const (
572+ prefix = `<script type="application/ld+json">`
573+ suffix = `</script>`
574+ templ = prefix + `"{{.}}"` + suffix
575+ )
576+ tpl := Must(New("JS string is JSON string").Parse(templ))
577+ for _, tt := range tests {
578+ t.Run(tt.name, func(t *testing.T) {
579+ var buf bytes.Buffer
580+ if err := tpl.Execute(&buf, tt.in); err != nil {
581+ t.Fatalf("Cannot render template: %v", err)
582+ }
583+ trimmed := bytes.TrimSuffix(bytes.TrimPrefix(buf.Bytes(), []byte(prefix)), []byte(suffix))
584+ var got string
585+ if err := json.Unmarshal(trimmed, &got); err != nil {
586+ t.Fatalf("Cannot parse JS string %q as JSON: %v", trimmed[1:len(trimmed)-1], err)
587+ }
588+ if got != tt.in {
589+ t.Errorf("Serialization changed the string value: got %q want %q", got, tt.in)
590+ }
591+ })
592+ }
593+}
594+
595 type testCase struct {
596 t *testing.T
597 root *Template
598diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
599index 77294ed..b8a809e 100644
600--- a/src/text/template/exec_test.go
601+++ b/src/text/template/exec_test.go
602@@ -911,9 +911,9 @@ func TestJSEscaping(t *testing.T) {
603 {`Go "jump" \`, `Go \"jump\" \\`},
604 {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`},
605 {"unprintable \uFDFF", `unprintable \uFDFF`},
606- {`<html>`, `\x3Chtml\x3E`},
607- {`no = in attributes`, `no \x3D in attributes`},
608- {`&#x27; does not become HTML entity`, `\x26#x27; does not become HTML entity`},
609+ {`<html>`, `\u003Chtml\u003E`},
610+ {`no = in attributes`, `no \u003D in attributes`},
611+ {`&#x27; does not become HTML entity`, `\u0026#x27; does not become HTML entity`},
612 }
613 for _, tc := range testCases {
614 s := JSEscapeString(tc.in)
176diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go 615diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
177index 46125bc..f3de9fb 100644 616index 46125bc..f3de9fb 100644
178--- a/src/text/template/funcs.go 617--- a/src/text/template/funcs.go
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch
new file mode 100644
index 0000000000..cd7dd0957c
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch
@@ -0,0 +1,393 @@
1From 7ddce23c7d5b728acf8482f5006497c7b9915f8a Mon Sep 17 00:00:00 2001
2From: Ariel Mashraki <ariel@mashraki.co.il>
3Date: Wed, 22 Apr 2020 22:17:56 +0300
4Subject: [PATCH 3/6] text/template: add CommentNode to template parse tree
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Fixes #34652
10
11Change-Id: Icf6e3eda593fed826736f34f95a9d66f5450cc98
12Reviewed-on: https://go-review.googlesource.com/c/go/+/229398
13Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
14Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
15TryBot-Result: Gobot Gobot <gobot@golang.org>
16
17Dependency Patch #3
18
19Upstream-Status: Backport from https://github.com/golang/go/commit/c8ea03828b0645b1fd5725888e44873b75fcfbb6
20CVE: CVE-2023-24538
21Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
22---
23 api/next.txt | 19 +++++++++++++++++++
24 src/html/template/escape.go | 2 ++
25 src/html/template/template_test.go | 16 ++++++++++++++++
26 src/text/template/exec.go | 1 +
27 src/text/template/parse/lex.go | 8 +++++++-
28 src/text/template/parse/lex_test.go | 7 +++++--
29 src/text/template/parse/node.go | 33 +++++++++++++++++++++++++++++++++
30 src/text/template/parse/parse.go | 22 +++++++++++++++++++---
31 src/text/template/parse/parse_test.go | 25 +++++++++++++++++++++++++
32 9 files changed, 127 insertions(+), 6 deletions(-)
33
34diff --git a/api/next.txt b/api/next.txt
35index e69de29..076f39e 100644
36--- a/api/next.txt
37+++ b/api/next.txt
38@@ -0,0 +1,19 @@
39+pkg unicode, const Version = "13.0.0"
40+pkg unicode, var Chorasmian *RangeTable
41+pkg unicode, var Dives_Akuru *RangeTable
42+pkg unicode, var Khitan_Small_Script *RangeTable
43+pkg unicode, var Yezidi *RangeTable
44+pkg text/template/parse, const NodeComment = 20
45+pkg text/template/parse, const NodeComment NodeType
46+pkg text/template/parse, const ParseComments = 1
47+pkg text/template/parse, const ParseComments Mode
48+pkg text/template/parse, method (*CommentNode) Copy() Node
49+pkg text/template/parse, method (*CommentNode) String() string
50+pkg text/template/parse, method (CommentNode) Position() Pos
51+pkg text/template/parse, method (CommentNode) Type() NodeType
52+pkg text/template/parse, type CommentNode struct
53+pkg text/template/parse, type CommentNode struct, Text string
54+pkg text/template/parse, type CommentNode struct, embedded NodeType
55+pkg text/template/parse, type CommentNode struct, embedded Pos
56+pkg text/template/parse, type Mode uint
57+pkg text/template/parse, type Tree struct, Mode Mode
58diff --git a/src/html/template/escape.go b/src/html/template/escape.go
59index f12dafa..8739735 100644
60--- a/src/html/template/escape.go
61+++ b/src/html/template/escape.go
62@@ -124,6 +124,8 @@ func (e *escaper) escape(c context, n parse.Node) context {
63 switch n := n.(type) {
64 case *parse.ActionNode:
65 return e.escapeAction(c, n)
66+ case *parse.CommentNode:
67+ return c
68 case *parse.IfNode:
69 return e.escapeBranch(c, &n.BranchNode, "if")
70 case *parse.ListNode:
71diff --git a/src/html/template/template_test.go b/src/html/template/template_test.go
72index 86bd4db..1f2c888 100644
73--- a/src/html/template/template_test.go
74+++ b/src/html/template/template_test.go
75@@ -10,6 +10,7 @@ import (
76 . "html/template"
77 "strings"
78 "testing"
79+ "text/template/parse"
80 )
81
82 func TestTemplateClone(t *testing.T) {
83@@ -160,6 +161,21 @@ func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) {
84 }
85 }
86
87+func TestSkipEscapeComments(t *testing.T) {
88+ c := newTestCase(t)
89+ tr := parse.New("root")
90+ tr.Mode = parse.ParseComments
91+ newT, err := tr.Parse("{{/* A comment */}}{{ 1 }}{{/* Another comment */}}", "", "", make(map[string]*parse.Tree))
92+ if err != nil {
93+ t.Fatalf("Cannot parse template text: %v", err)
94+ }
95+ c.root, err = c.root.AddParseTree("root", newT)
96+ if err != nil {
97+ t.Fatalf("Cannot add parse tree to template: %v", err)
98+ }
99+ c.mustExecute(c.root, nil, "1")
100+}
101+
102 type testCase struct {
103 t *testing.T
104 root *Template
105diff --git a/src/text/template/exec.go b/src/text/template/exec.go
106index ac3e741..7ac5175 100644
107--- a/src/text/template/exec.go
108+++ b/src/text/template/exec.go
109@@ -256,6 +256,7 @@ func (s *state) walk(dot reflect.Value, node parse.Node) {
110 if len(node.Pipe.Decl) == 0 {
111 s.printValue(node, val)
112 }
113+ case *parse.CommentNode:
114 case *parse.IfNode:
115 s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList)
116 case *parse.ListNode:
117diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
118index 30371f2..e41373a 100644
119--- a/src/text/template/parse/lex.go
120+++ b/src/text/template/parse/lex.go
121@@ -41,6 +41,7 @@ const (
122 itemBool // boolean constant
123 itemChar // printable ASCII character; grab bag for comma etc.
124 itemCharConstant // character constant
125+ itemComment // comment text
126 itemComplex // complex constant (1+2i); imaginary is just a number
127 itemAssign // equals ('=') introducing an assignment
128 itemDeclare // colon-equals (':=') introducing a declaration
129@@ -112,6 +113,7 @@ type lexer struct {
130 leftDelim string // start of action
131 rightDelim string // end of action
132 trimRightDelim string // end of action with trim marker
133+ emitComment bool // emit itemComment tokens.
134 pos Pos // current position in the input
135 start Pos // start position of this item
136 width Pos // width of last rune read from input
137@@ -203,7 +205,7 @@ func (l *lexer) drain() {
138 }
139
140 // lex creates a new scanner for the input string.
141-func lex(name, input, left, right string) *lexer {
142+func lex(name, input, left, right string, emitComment bool) *lexer {
143 if left == "" {
144 left = leftDelim
145 }
146@@ -216,6 +218,7 @@ func lex(name, input, left, right string) *lexer {
147 leftDelim: left,
148 rightDelim: right,
149 trimRightDelim: rightTrimMarker + right,
150+ emitComment: emitComment,
151 items: make(chan item),
152 line: 1,
153 startLine: 1,
154@@ -323,6 +326,9 @@ func lexComment(l *lexer) stateFn {
155 if !delim {
156 return l.errorf("comment ends before closing delimiter")
157 }
158+ if l.emitComment {
159+ l.emit(itemComment)
160+ }
161 if trimSpace {
162 l.pos += trimMarkerLen
163 }
164diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
165index 563c4fc..f6d5f28 100644
166--- a/src/text/template/parse/lex_test.go
167+++ b/src/text/template/parse/lex_test.go
168@@ -15,6 +15,7 @@ var itemName = map[itemType]string{
169 itemBool: "bool",
170 itemChar: "char",
171 itemCharConstant: "charconst",
172+ itemComment: "comment",
173 itemComplex: "complex",
174 itemDeclare: ":=",
175 itemEOF: "EOF",
176@@ -90,6 +91,7 @@ var lexTests = []lexTest{
177 {"text", `now is the time`, []item{mkItem(itemText, "now is the time"), tEOF}},
178 {"text with comment", "hello-{{/* this is a comment */}}-world", []item{
179 mkItem(itemText, "hello-"),
180+ mkItem(itemComment, "/* this is a comment */"),
181 mkItem(itemText, "-world"),
182 tEOF,
183 }},
184@@ -311,6 +313,7 @@ var lexTests = []lexTest{
185 }},
186 {"trimming spaces before and after comment", "hello- {{- /* hello */ -}} -world", []item{
187 mkItem(itemText, "hello-"),
188+ mkItem(itemComment, "/* hello */"),
189 mkItem(itemText, "-world"),
190 tEOF,
191 }},
192@@ -389,7 +392,7 @@ var lexTests = []lexTest{
193
194 // collect gathers the emitted items into a slice.
195 func collect(t *lexTest, left, right string) (items []item) {
196- l := lex(t.name, t.input, left, right)
197+ l := lex(t.name, t.input, left, right, true)
198 for {
199 item := l.nextItem()
200 items = append(items, item)
201@@ -529,7 +532,7 @@ func TestPos(t *testing.T) {
202 func TestShutdown(t *testing.T) {
203 // We need to duplicate template.Parse here to hold on to the lexer.
204 const text = "erroneous{{define}}{{else}}1234"
205- lexer := lex("foo", text, "{{", "}}")
206+ lexer := lex("foo", text, "{{", "}}", false)
207 _, err := New("root").parseLexer(lexer)
208 if err == nil {
209 t.Fatalf("expected error")
210diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go
211index 1c116ea..a9dad5e 100644
212--- a/src/text/template/parse/node.go
213+++ b/src/text/template/parse/node.go
214@@ -70,6 +70,7 @@ const (
215 NodeTemplate // A template invocation action.
216 NodeVariable // A $ variable.
217 NodeWith // A with action.
218+ NodeComment // A comment.
219 )
220
221 // Nodes.
222@@ -149,6 +150,38 @@ func (t *TextNode) Copy() Node {
223 return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: append([]byte{}, t.Text...)}
224 }
225
226+// CommentNode holds a comment.
227+type CommentNode struct {
228+ NodeType
229+ Pos
230+ tr *Tree
231+ Text string // Comment text.
232+}
233+
234+func (t *Tree) newComment(pos Pos, text string) *CommentNode {
235+ return &CommentNode{tr: t, NodeType: NodeComment, Pos: pos, Text: text}
236+}
237+
238+func (c *CommentNode) String() string {
239+ var sb strings.Builder
240+ c.writeTo(&sb)
241+ return sb.String()
242+}
243+
244+func (c *CommentNode) writeTo(sb *strings.Builder) {
245+ sb.WriteString("{{")
246+ sb.WriteString(c.Text)
247+ sb.WriteString("}}")
248+}
249+
250+func (c *CommentNode) tree() *Tree {
251+ return c.tr
252+}
253+
254+func (c *CommentNode) Copy() Node {
255+ return &CommentNode{tr: c.tr, NodeType: NodeComment, Pos: c.Pos, Text: c.Text}
256+}
257+
258 // PipeNode holds a pipeline with optional declaration
259 type PipeNode struct {
260 NodeType
261diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
262index c9b80f4..496d8bf 100644
263--- a/src/text/template/parse/parse.go
264+++ b/src/text/template/parse/parse.go
265@@ -21,6 +21,7 @@ type Tree struct {
266 Name string // name of the template represented by the tree.
267 ParseName string // name of the top-level template during parsing, for error messages.
268 Root *ListNode // top-level root of the tree.
269+ Mode Mode // parsing mode.
270 text string // text parsed to create the template (or its parent)
271 // Parsing only; cleared after parse.
272 funcs []map[string]interface{}
273@@ -29,8 +30,16 @@ type Tree struct {
274 peekCount int
275 vars []string // variables defined at the moment.
276 treeSet map[string]*Tree
277+ mode Mode
278 }
279
280+// A mode value is a set of flags (or 0). Modes control parser behavior.
281+type Mode uint
282+
283+const (
284+ ParseComments Mode = 1 << iota // parse comments and add them to AST
285+)
286+
287 // Copy returns a copy of the Tree. Any parsing state is discarded.
288 func (t *Tree) Copy() *Tree {
289 if t == nil {
290@@ -220,7 +229,8 @@ func (t *Tree) stopParse() {
291 func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) {
292 defer t.recover(&err)
293 t.ParseName = t.Name
294- t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim), treeSet)
295+ emitComment := t.Mode&ParseComments != 0
296+ t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim, emitComment), treeSet)
297 t.text = text
298 t.parse()
299 t.add()
300@@ -240,12 +250,14 @@ func (t *Tree) add() {
301 }
302 }
303
304-// IsEmptyTree reports whether this tree (node) is empty of everything but space.
305+// IsEmptyTree reports whether this tree (node) is empty of everything but space or comments.
306 func IsEmptyTree(n Node) bool {
307 switch n := n.(type) {
308 case nil:
309 return true
310 case *ActionNode:
311+ case *CommentNode:
312+ return true
313 case *IfNode:
314 case *ListNode:
315 for _, node := range n.Nodes {
316@@ -276,6 +288,7 @@ func (t *Tree) parse() {
317 if t.nextNonSpace().typ == itemDefine {
318 newT := New("definition") // name will be updated once we know it.
319 newT.text = t.text
320+ newT.Mode = t.Mode
321 newT.ParseName = t.ParseName
322 newT.startParse(t.funcs, t.lex, t.treeSet)
323 newT.parseDefinition()
324@@ -331,13 +344,15 @@ func (t *Tree) itemList() (list *ListNode, next Node) {
325 }
326
327 // textOrAction:
328-// text | action
329+// text | comment | action
330 func (t *Tree) textOrAction() Node {
331 switch token := t.nextNonSpace(); token.typ {
332 case itemText:
333 return t.newText(token.pos, token.val)
334 case itemLeftDelim:
335 return t.action()
336+ case itemComment:
337+ return t.newComment(token.pos, token.val)
338 default:
339 t.unexpected(token, "input")
340 }
341@@ -539,6 +554,7 @@ func (t *Tree) blockControl() Node {
342
343 block := New(name) // name will be updated once we know it.
344 block.text = t.text
345+ block.Mode = t.Mode
346 block.ParseName = t.ParseName
347 block.startParse(t.funcs, t.lex, t.treeSet)
348 var end Node
349diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
350index 4e09a78..d9c13c5 100644
351--- a/src/text/template/parse/parse_test.go
352+++ b/src/text/template/parse/parse_test.go
353@@ -348,6 +348,30 @@ func TestParseCopy(t *testing.T) {
354 testParse(true, t)
355 }
356
357+func TestParseWithComments(t *testing.T) {
358+ textFormat = "%q"
359+ defer func() { textFormat = "%s" }()
360+ tests := [...]parseTest{
361+ {"comment", "{{/*\n\n\n*/}}", noError, "{{/*\n\n\n*/}}"},
362+ {"comment trim left", "x \r\n\t{{- /* hi */}}", noError, `"x"{{/* hi */}}`},
363+ {"comment trim right", "{{/* hi */ -}}\n\n\ty", noError, `{{/* hi */}}"y"`},
364+ {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", noError, `"x"{{/* */}}"y"`},
365+ }
366+ for _, test := range tests {
367+ t.Run(test.name, func(t *testing.T) {
368+ tr := New(test.name)
369+ tr.Mode = ParseComments
370+ tmpl, err := tr.Parse(test.input, "", "", make(map[string]*Tree))
371+ if err != nil {
372+ t.Errorf("%q: expected error; got none", test.name)
373+ }
374+ if result := tmpl.Root.String(); result != test.result {
375+ t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result)
376+ }
377+ })
378+ }
379+}
380+
381 type isEmptyTest struct {
382 name string
383 input string
384@@ -358,6 +382,7 @@ var isEmptyTests = []isEmptyTest{
385 {"empty", ``, true},
386 {"nonempty", `hello`, false},
387 {"spaces only", " \t\n \t\n", true},
388+ {"comment only", "{{/* comment */}}", true},
389 {"definition", `{{define "x"}}something{{end}}`, true},
390 {"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true},
391 {"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n", false},
392--
3932.7.4
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch
new file mode 100644
index 0000000000..d5e2eb6684
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch
@@ -0,0 +1,497 @@
1From 760d88497091fb5d6d231a18e6f4e06ecb9af9b2 Mon Sep 17 00:00:00 2001
2From: Russ Cox <rsc@golang.org>
3Date: Thu, 10 Sep 2020 18:53:26 -0400
4Subject: [PATCH 4/6] text/template: allow newlines inside action delimiters
5
6This allows multiline constructs like:
7
8 {{"hello" |
9 printf}}
10
11Now that unclosed actions can span multiple lines,
12track and report the start of the action when reporting errors.
13
14Also clean up a few "unexpected <error message>" to be just "<error message>".
15
16Fixes #29770.
17
18Change-Id: I54c6c016029a8328b7902a4b6d85eab713ec3285
19Reviewed-on: https://go-review.googlesource.com/c/go/+/254257
20Trust: Russ Cox <rsc@golang.org>
21Run-TryBot: Russ Cox <rsc@golang.org>
22TryBot-Result: Go Bot <gobot@golang.org>
23Reviewed-by: Rob Pike <r@golang.org>
24
25Dependency Patch #4
26
27Upstream-Status: Backport from https://github.com/golang/go/commit/9384d34c58099657bb1b133beaf3ff37ada9b017
28CVE: CVE-2023-24538
29Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
30---
31 src/text/template/doc.go | 21 ++++-----
32 src/text/template/exec_test.go | 2 +-
33 src/text/template/parse/lex.go | 84 +++++++++++++++++------------------
34 src/text/template/parse/lex_test.go | 2 +-
35 src/text/template/parse/parse.go | 59 +++++++++++++-----------
36 src/text/template/parse/parse_test.go | 36 ++++++++++++---
37 6 files changed, 117 insertions(+), 87 deletions(-)
38
39diff --git a/src/text/template/doc.go b/src/text/template/doc.go
40index 4b0efd2..7b30294 100644
41--- a/src/text/template/doc.go
42+++ b/src/text/template/doc.go
43@@ -40,16 +40,17 @@ More intricate examples appear below.
44 Text and spaces
45
46 By default, all text between actions is copied verbatim when the template is
47-executed. For example, the string " items are made of " in the example above appears
48-on standard output when the program is run.
49-
50-However, to aid in formatting template source code, if an action's left delimiter
51-(by default "{{") is followed immediately by a minus sign and ASCII space character
52-("{{- "), all trailing white space is trimmed from the immediately preceding text.
53-Similarly, if the right delimiter ("}}") is preceded by a space and minus sign
54-(" -}}"), all leading white space is trimmed from the immediately following text.
55-In these trim markers, the ASCII space must be present; "{{-3}}" parses as an
56-action containing the number -3.
57+executed. For example, the string " items are made of " in the example above
58+appears on standard output when the program is run.
59+
60+However, to aid in formatting template source code, if an action's left
61+delimiter (by default "{{") is followed immediately by a minus sign and white
62+space, all trailing white space is trimmed from the immediately preceding text.
63+Similarly, if the right delimiter ("}}") is preceded by white space and a minus
64+sign, all leading white space is trimmed from the immediately following text.
65+In these trim markers, the white space must be present:
66+"{{- 3}}" is like "{{3}}" but trims the immediately preceding text, while
67+"{{-3}}" parses as an action containing the number -3.
68
69 For instance, when executing the template whose source is
70
71diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
72index b8a809e..3309b33 100644
73--- a/src/text/template/exec_test.go
74+++ b/src/text/template/exec_test.go
75@@ -1295,7 +1295,7 @@ func TestUnterminatedStringError(t *testing.T) {
76 t.Fatal("expected error")
77 }
78 str := err.Error()
79- if !strings.Contains(str, "X:3: unexpected unterminated raw quoted string") {
80+ if !strings.Contains(str, "X:3: unterminated raw quoted string") {
81 t.Fatalf("unexpected error: %s", str)
82 }
83 }
84diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
85index e41373a..6784071 100644
86--- a/src/text/template/parse/lex.go
87+++ b/src/text/template/parse/lex.go
88@@ -92,15 +92,14 @@ const eof = -1
89 // If the action begins "{{- " rather than "{{", then all space/tab/newlines
90 // preceding the action are trimmed; conversely if it ends " -}}" the
91 // leading spaces are trimmed. This is done entirely in the lexer; the
92-// parser never sees it happen. We require an ASCII space to be
93-// present to avoid ambiguity with things like "{{-3}}". It reads
94+// parser never sees it happen. We require an ASCII space (' ', \t, \r, \n)
95+// to be present to avoid ambiguity with things like "{{-3}}". It reads
96 // better with the space present anyway. For simplicity, only ASCII
97-// space does the job.
98+// does the job.
99 const (
100- spaceChars = " \t\r\n" // These are the space characters defined by Go itself.
101- leftTrimMarker = "- " // Attached to left delimiter, trims trailing spaces from preceding text.
102- rightTrimMarker = " -" // Attached to right delimiter, trims leading spaces from following text.
103- trimMarkerLen = Pos(len(leftTrimMarker))
104+ spaceChars = " \t\r\n" // These are the space characters defined by Go itself.
105+ trimMarker = '-' // Attached to left/right delimiter, trims trailing spaces from preceding/following text.
106+ trimMarkerLen = Pos(1 + 1) // marker plus space before or after
107 )
108
109 // stateFn represents the state of the scanner as a function that returns the next state.
110@@ -108,19 +107,18 @@ type stateFn func(*lexer) stateFn
111
112 // lexer holds the state of the scanner.
113 type lexer struct {
114- name string // the name of the input; used only for error reports
115- input string // the string being scanned
116- leftDelim string // start of action
117- rightDelim string // end of action
118- trimRightDelim string // end of action with trim marker
119- emitComment bool // emit itemComment tokens.
120- pos Pos // current position in the input
121- start Pos // start position of this item
122- width Pos // width of last rune read from input
123- items chan item // channel of scanned items
124- parenDepth int // nesting depth of ( ) exprs
125- line int // 1+number of newlines seen
126- startLine int // start line of this item
127+ name string // the name of the input; used only for error reports
128+ input string // the string being scanned
129+ leftDelim string // start of action
130+ rightDelim string // end of action
131+ emitComment bool // emit itemComment tokens.
132+ pos Pos // current position in the input
133+ start Pos // start position of this item
134+ width Pos // width of last rune read from input
135+ items chan item // channel of scanned items
136+ parenDepth int // nesting depth of ( ) exprs
137+ line int // 1+number of newlines seen
138+ startLine int // start line of this item
139 }
140
141 // next returns the next rune in the input.
142@@ -213,15 +211,14 @@ func lex(name, input, left, right string, emitComment bool) *lexer {
143 right = rightDelim
144 }
145 l := &lexer{
146- name: name,
147- input: input,
148- leftDelim: left,
149- rightDelim: right,
150- trimRightDelim: rightTrimMarker + right,
151- emitComment: emitComment,
152- items: make(chan item),
153- line: 1,
154- startLine: 1,
155+ name: name,
156+ input: input,
157+ leftDelim: left,
158+ rightDelim: right,
159+ emitComment: emitComment,
160+ items: make(chan item),
161+ line: 1,
162+ startLine: 1,
163 }
164 go l.run()
165 return l
166@@ -251,7 +248,7 @@ func lexText(l *lexer) stateFn {
167 ldn := Pos(len(l.leftDelim))
168 l.pos += Pos(x)
169 trimLength := Pos(0)
170- if strings.HasPrefix(l.input[l.pos+ldn:], leftTrimMarker) {
171+ if hasLeftTrimMarker(l.input[l.pos+ldn:]) {
172 trimLength = rightTrimLength(l.input[l.start:l.pos])
173 }
174 l.pos -= trimLength
175@@ -280,7 +277,7 @@ func rightTrimLength(s string) Pos {
176
177 // atRightDelim reports whether the lexer is at a right delimiter, possibly preceded by a trim marker.
178 func (l *lexer) atRightDelim() (delim, trimSpaces bool) {
179- if strings.HasPrefix(l.input[l.pos:], l.trimRightDelim) { // With trim marker.
180+ if hasRightTrimMarker(l.input[l.pos:]) && strings.HasPrefix(l.input[l.pos+trimMarkerLen:], l.rightDelim) { // With trim marker.
181 return true, true
182 }
183 if strings.HasPrefix(l.input[l.pos:], l.rightDelim) { // Without trim marker.
184@@ -297,7 +294,7 @@ func leftTrimLength(s string) Pos {
185 // lexLeftDelim scans the left delimiter, which is known to be present, possibly with a trim marker.
186 func lexLeftDelim(l *lexer) stateFn {
187 l.pos += Pos(len(l.leftDelim))
188- trimSpace := strings.HasPrefix(l.input[l.pos:], leftTrimMarker)
189+ trimSpace := hasLeftTrimMarker(l.input[l.pos:])
190 afterMarker := Pos(0)
191 if trimSpace {
192 afterMarker = trimMarkerLen
193@@ -342,7 +339,7 @@ func lexComment(l *lexer) stateFn {
194
195 // lexRightDelim scans the right delimiter, which is known to be present, possibly with a trim marker.
196 func lexRightDelim(l *lexer) stateFn {
197- trimSpace := strings.HasPrefix(l.input[l.pos:], rightTrimMarker)
198+ trimSpace := hasRightTrimMarker(l.input[l.pos:])
199 if trimSpace {
200 l.pos += trimMarkerLen
201 l.ignore()
202@@ -369,7 +366,7 @@ func lexInsideAction(l *lexer) stateFn {
203 return l.errorf("unclosed left paren")
204 }
205 switch r := l.next(); {
206- case r == eof || isEndOfLine(r):
207+ case r == eof:
208 return l.errorf("unclosed action")
209 case isSpace(r):
210 l.backup() // Put space back in case we have " -}}".
211@@ -439,7 +436,7 @@ func lexSpace(l *lexer) stateFn {
212 }
213 // Be careful about a trim-marked closing delimiter, which has a minus
214 // after a space. We know there is a space, so check for the '-' that might follow.
215- if strings.HasPrefix(l.input[l.pos-1:], l.trimRightDelim) {
216+ if hasRightTrimMarker(l.input[l.pos-1:]) && strings.HasPrefix(l.input[l.pos-1+trimMarkerLen:], l.rightDelim) {
217 l.backup() // Before the space.
218 if numSpaces == 1 {
219 return lexRightDelim // On the delim, so go right to that.
220@@ -526,7 +523,7 @@ func lexFieldOrVariable(l *lexer, typ itemType) stateFn {
221 // day to implement arithmetic.
222 func (l *lexer) atTerminator() bool {
223 r := l.peek()
224- if isSpace(r) || isEndOfLine(r) {
225+ if isSpace(r) {
226 return true
227 }
228 switch r {
229@@ -657,15 +654,18 @@ Loop:
230
231 // isSpace reports whether r is a space character.
232 func isSpace(r rune) bool {
233- return r == ' ' || r == '\t'
234-}
235-
236-// isEndOfLine reports whether r is an end-of-line character.
237-func isEndOfLine(r rune) bool {
238- return r == '\r' || r == '\n'
239+ return r == ' ' || r == '\t' || r == '\r' || r == '\n'
240 }
241
242 // isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
243 func isAlphaNumeric(r rune) bool {
244 return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
245 }
246+
247+func hasLeftTrimMarker(s string) bool {
248+ return len(s) >= 2 && s[0] == trimMarker && isSpace(rune(s[1]))
249+}
250+
251+func hasRightTrimMarker(s string) bool {
252+ return len(s) >= 2 && isSpace(rune(s[0])) && s[1] == trimMarker
253+}
254diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
255index f6d5f28..6510eed 100644
256--- a/src/text/template/parse/lex_test.go
257+++ b/src/text/template/parse/lex_test.go
258@@ -323,7 +323,7 @@ var lexTests = []lexTest{
259 tLeft,
260 mkItem(itemError, "unrecognized character in action: U+0001"),
261 }},
262- {"unclosed action", "{{\n}}", []item{
263+ {"unclosed action", "{{", []item{
264 tLeft,
265 mkItem(itemError, "unclosed action"),
266 }},
267diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
268index 496d8bf..5e6e512 100644
269--- a/src/text/template/parse/parse.go
270+++ b/src/text/template/parse/parse.go
271@@ -24,13 +24,14 @@ type Tree struct {
272 Mode Mode // parsing mode.
273 text string // text parsed to create the template (or its parent)
274 // Parsing only; cleared after parse.
275- funcs []map[string]interface{}
276- lex *lexer
277- token [3]item // three-token lookahead for parser.
278- peekCount int
279- vars []string // variables defined at the moment.
280- treeSet map[string]*Tree
281- mode Mode
282+ funcs []map[string]interface{}
283+ lex *lexer
284+ token [3]item // three-token lookahead for parser.
285+ peekCount int
286+ vars []string // variables defined at the moment.
287+ treeSet map[string]*Tree
288+ actionLine int // line of left delim starting action
289+ mode Mode
290 }
291
292 // A mode value is a set of flags (or 0). Modes control parser behavior.
293@@ -187,6 +188,16 @@ func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item {
294
295 // unexpected complains about the token and terminates processing.
296 func (t *Tree) unexpected(token item, context string) {
297+ if token.typ == itemError {
298+ extra := ""
299+ if t.actionLine != 0 && t.actionLine != token.line {
300+ extra = fmt.Sprintf(" in action started at %s:%d", t.ParseName, t.actionLine)
301+ if strings.HasSuffix(token.val, " action") {
302+ extra = extra[len(" in action"):] // avoid "action in action"
303+ }
304+ }
305+ t.errorf("%s%s", token, extra)
306+ }
307 t.errorf("unexpected %s in %s", token, context)
308 }
309
310@@ -350,6 +361,8 @@ func (t *Tree) textOrAction() Node {
311 case itemText:
312 return t.newText(token.pos, token.val)
313 case itemLeftDelim:
314+ t.actionLine = token.line
315+ defer t.clearActionLine()
316 return t.action()
317 case itemComment:
318 return t.newComment(token.pos, token.val)
319@@ -359,6 +372,10 @@ func (t *Tree) textOrAction() Node {
320 return nil
321 }
322
323+func (t *Tree) clearActionLine() {
324+ t.actionLine = 0
325+}
326+
327 // Action:
328 // control
329 // command ("|" command)*
330@@ -384,12 +401,12 @@ func (t *Tree) action() (n Node) {
331 t.backup()
332 token := t.peek()
333 // Do not pop variables; they persist until "end".
334- return t.newAction(token.pos, token.line, t.pipeline("command"))
335+ return t.newAction(token.pos, token.line, t.pipeline("command", itemRightDelim))
336 }
337
338 // Pipeline:
339 // declarations? command ('|' command)*
340-func (t *Tree) pipeline(context string) (pipe *PipeNode) {
341+func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) {
342 token := t.peekNonSpace()
343 pipe = t.newPipeline(token.pos, token.line, nil)
344 // Are there declarations or assignments?
345@@ -430,12 +447,9 @@ decls:
346 }
347 for {
348 switch token := t.nextNonSpace(); token.typ {
349- case itemRightDelim, itemRightParen:
350+ case end:
351 // At this point, the pipeline is complete
352 t.checkPipeline(pipe, context)
353- if token.typ == itemRightParen {
354- t.backup()
355- }
356 return
357 case itemBool, itemCharConstant, itemComplex, itemDot, itemField, itemIdentifier,
358 itemNumber, itemNil, itemRawString, itemString, itemVariable, itemLeftParen:
359@@ -464,7 +478,7 @@ func (t *Tree) checkPipeline(pipe *PipeNode, context string) {
360
361 func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) {
362 defer t.popVars(len(t.vars))
363- pipe = t.pipeline(context)
364+ pipe = t.pipeline(context, itemRightDelim)
365 var next Node
366 list, next = t.itemList()
367 switch next.Type() {
368@@ -550,7 +564,7 @@ func (t *Tree) blockControl() Node {
369
370 token := t.nextNonSpace()
371 name := t.parseTemplateName(token, context)
372- pipe := t.pipeline(context)
373+ pipe := t.pipeline(context, itemRightDelim)
374
375 block := New(name) // name will be updated once we know it.
376 block.text = t.text
377@@ -580,7 +594,7 @@ func (t *Tree) templateControl() Node {
378 if t.nextNonSpace().typ != itemRightDelim {
379 t.backup()
380 // Do not pop variables; they persist until "end".
381- pipe = t.pipeline(context)
382+ pipe = t.pipeline(context, itemRightDelim)
383 }
384 return t.newTemplate(token.pos, token.line, name, pipe)
385 }
386@@ -614,13 +628,12 @@ func (t *Tree) command() *CommandNode {
387 switch token := t.next(); token.typ {
388 case itemSpace:
389 continue
390- case itemError:
391- t.errorf("%s", token.val)
392 case itemRightDelim, itemRightParen:
393 t.backup()
394 case itemPipe:
395+ // nothing here; break loop below
396 default:
397- t.errorf("unexpected %s in operand", token)
398+ t.unexpected(token, "operand")
399 }
400 break
401 }
402@@ -675,8 +688,6 @@ func (t *Tree) operand() Node {
403 // A nil return means the next item is not a term.
404 func (t *Tree) term() Node {
405 switch token := t.nextNonSpace(); token.typ {
406- case itemError:
407- t.errorf("%s", token.val)
408 case itemIdentifier:
409 if !t.hasFunction(token.val) {
410 t.errorf("function %q not defined", token.val)
411@@ -699,11 +710,7 @@ func (t *Tree) term() Node {
412 }
413 return number
414 case itemLeftParen:
415- pipe := t.pipeline("parenthesized pipeline")
416- if token := t.next(); token.typ != itemRightParen {
417- t.errorf("unclosed right paren: unexpected %s", token)
418- }
419- return pipe
420+ return t.pipeline("parenthesized pipeline", itemRightParen)
421 case itemString, itemRawString:
422 s, err := strconv.Unquote(token.val)
423 if err != nil {
424diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
425index d9c13c5..220f984 100644
426--- a/src/text/template/parse/parse_test.go
427+++ b/src/text/template/parse/parse_test.go
428@@ -250,6 +250,13 @@ var parseTests = []parseTest{
429 {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", noError, `"x""y"`},
430 {"block definition", `{{block "foo" .}}hello{{end}}`, noError,
431 `{{template "foo" .}}`},
432+
433+ {"newline in assignment", "{{ $x \n := \n 1 \n }}", noError, "{{$x := 1}}"},
434+ {"newline in empty action", "{{\n}}", hasError, "{{\n}}"},
435+ {"newline in pipeline", "{{\n\"x\"\n|\nprintf\n}}", noError, `{{"x" | printf}}`},
436+ {"newline in comment", "{{/*\nhello\n*/}}", noError, ""},
437+ {"newline in comment", "{{-\n/*\nhello\n*/\n-}}", noError, ""},
438+
439 // Errors.
440 {"unclosed action", "hello{{range", hasError, ""},
441 {"unmatched end", "{{end}}", hasError, ""},
442@@ -426,23 +433,38 @@ var errorTests = []parseTest{
443 // Check line numbers are accurate.
444 {"unclosed1",
445 "line1\n{{",
446- hasError, `unclosed1:2: unexpected unclosed action in command`},
447+ hasError, `unclosed1:2: unclosed action`},
448 {"unclosed2",
449 "line1\n{{define `x`}}line2\n{{",
450- hasError, `unclosed2:3: unexpected unclosed action in command`},
451+ hasError, `unclosed2:3: unclosed action`},
452+ {"unclosed3",
453+ "line1\n{{\"x\"\n\"y\"\n",
454+ hasError, `unclosed3:4: unclosed action started at unclosed3:2`},
455+ {"unclosed4",
456+ "{{\n\n\n\n\n",
457+ hasError, `unclosed4:6: unclosed action started at unclosed4:1`},
458+ {"var1",
459+ "line1\n{{\nx\n}}",
460+ hasError, `var1:3: function "x" not defined`},
461 // Specific errors.
462 {"function",
463 "{{foo}}",
464 hasError, `function "foo" not defined`},
465- {"comment",
466+ {"comment1",
467 "{{/*}}",
468- hasError, `unclosed comment`},
469+ hasError, `comment1:1: unclosed comment`},
470+ {"comment2",
471+ "{{/*\nhello\n}}",
472+ hasError, `comment2:1: unclosed comment`},
473 {"lparen",
474 "{{.X (1 2 3}}",
475 hasError, `unclosed left paren`},
476 {"rparen",
477- "{{.X 1 2 3)}}",
478- hasError, `unexpected ")"`},
479+ "{{.X 1 2 3 ) }}",
480+ hasError, `unexpected ")" in command`},
481+ {"rparen2",
482+ "{{(.X 1 2 3",
483+ hasError, `unclosed action`},
484 {"space",
485 "{{`x`3}}",
486 hasError, `in operand`},
487@@ -488,7 +510,7 @@ var errorTests = []parseTest{
488 hasError, `missing value for parenthesized pipeline`},
489 {"multilinerawstring",
490 "{{ $v := `\n` }} {{",
491- hasError, `multilinerawstring:2: unexpected unclosed action`},
492+ hasError, `multilinerawstring:2: unclosed action`},
493 {"rangeundefvar",
494 "{{range $k}}{{end}}",
495 hasError, `undefined variable`},
496--
4972.7.4
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_5.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_5.patch
new file mode 100644
index 0000000000..fc38929648
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_5.patch
@@ -0,0 +1,585 @@
1From e0e6bca6ddc0e6d9fa3a5b644af9b446924fbf83 Mon Sep 17 00:00:00 2001
2From: Russ Cox <rsc@golang.org>
3Date: Thu, 20 May 2021 12:46:33 -0400
4Subject: [PATCH 5/6] html/template, text/template: implement break and
5 continue for range loops
6
7Break and continue for range loops was accepted as a proposal in June 2017.
8It was implemented in CL 66410 (Oct 2017)
9but then rolled back in CL 92155 (Feb 2018)
10because html/template changes had not been implemented.
11
12This CL reimplements break and continue in text/template
13and then adds support for them in html/template as well.
14
15Fixes #20531.
16
17Change-Id: I05330482a976f1c078b4b49c2287bd9031bb7616
18Reviewed-on: https://go-review.googlesource.com/c/go/+/321491
19Trust: Russ Cox <rsc@golang.org>
20Run-TryBot: Russ Cox <rsc@golang.org>
21TryBot-Result: Go Bot <gobot@golang.org>
22Reviewed-by: Rob Pike <r@golang.org>
23
24Dependency Patch #5
25
26Upstream-Status: Backport from https://github.com/golang/go/commit/d0dd26a88c019d54f22463daae81e785f5867565
27CVE: CVE-2023-24538
28Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
29---
30 src/html/template/context.go | 4 ++
31 src/html/template/escape.go | 71 ++++++++++++++++++++++++++++++++++-
32 src/html/template/escape_test.go | 24 ++++++++++++
33 src/text/template/doc.go | 8 ++++
34 src/text/template/exec.go | 24 +++++++++++-
35 src/text/template/exec_test.go | 2 +
36 src/text/template/parse/lex.go | 13 ++++++-
37 src/text/template/parse/lex_test.go | 2 +
38 src/text/template/parse/node.go | 36 ++++++++++++++++++
39 src/text/template/parse/parse.go | 42 ++++++++++++++++++++-
40 src/text/template/parse/parse_test.go | 8 ++++
41 11 files changed, 230 insertions(+), 4 deletions(-)
42
43diff --git a/src/html/template/context.go b/src/html/template/context.go
44index f7d4849..aaa7d08 100644
45--- a/src/html/template/context.go
46+++ b/src/html/template/context.go
47@@ -6,6 +6,7 @@ package template
48
49 import (
50 "fmt"
51+ "text/template/parse"
52 )
53
54 // context describes the state an HTML parser must be in when it reaches the
55@@ -22,6 +23,7 @@ type context struct {
56 jsCtx jsCtx
57 attr attr
58 element element
59+ n parse.Node // for range break/continue
60 err *Error
61 }
62
63@@ -141,6 +143,8 @@ const (
64 // stateError is an infectious error state outside any valid
65 // HTML/CSS/JS construct.
66 stateError
67+ // stateDead marks unreachable code after a {{break}} or {{continue}}.
68+ stateDead
69 )
70
71 // isComment is true for any state that contains content meant for template
72diff --git a/src/html/template/escape.go b/src/html/template/escape.go
73index 8739735..6dea79c 100644
74--- a/src/html/template/escape.go
75+++ b/src/html/template/escape.go
76@@ -97,6 +97,15 @@ type escaper struct {
77 actionNodeEdits map[*parse.ActionNode][]string
78 templateNodeEdits map[*parse.TemplateNode]string
79 textNodeEdits map[*parse.TextNode][]byte
80+ // rangeContext holds context about the current range loop.
81+ rangeContext *rangeContext
82+}
83+
84+// rangeContext holds information about the current range loop.
85+type rangeContext struct {
86+ outer *rangeContext // outer loop
87+ breaks []context // context at each break action
88+ continues []context // context at each continue action
89 }
90
91 // makeEscaper creates a blank escaper for the given set.
92@@ -109,6 +118,7 @@ func makeEscaper(n *nameSpace) escaper {
93 map[*parse.ActionNode][]string{},
94 map[*parse.TemplateNode]string{},
95 map[*parse.TextNode][]byte{},
96+ nil,
97 }
98 }
99
100@@ -124,8 +134,16 @@ func (e *escaper) escape(c context, n parse.Node) context {
101 switch n := n.(type) {
102 case *parse.ActionNode:
103 return e.escapeAction(c, n)
104+ case *parse.BreakNode:
105+ c.n = n
106+ e.rangeContext.breaks = append(e.rangeContext.breaks, c)
107+ return context{state: stateDead}
108 case *parse.CommentNode:
109 return c
110+ case *parse.ContinueNode:
111+ c.n = n
112+ e.rangeContext.continues = append(e.rangeContext.breaks, c)
113+ return context{state: stateDead}
114 case *parse.IfNode:
115 return e.escapeBranch(c, &n.BranchNode, "if")
116 case *parse.ListNode:
117@@ -427,6 +445,12 @@ func join(a, b context, node parse.Node, nodeName string) context {
118 if b.state == stateError {
119 return b
120 }
121+ if a.state == stateDead {
122+ return b
123+ }
124+ if b.state == stateDead {
125+ return a
126+ }
127 if a.eq(b) {
128 return a
129 }
130@@ -466,14 +490,27 @@ func join(a, b context, node parse.Node, nodeName string) context {
131
132 // escapeBranch escapes a branch template node: "if", "range" and "with".
133 func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) context {
134+ if nodeName == "range" {
135+ e.rangeContext = &rangeContext{outer: e.rangeContext}
136+ }
137 c0 := e.escapeList(c, n.List)
138- if nodeName == "range" && c0.state != stateError {
139+ if nodeName == "range" {
140+ if c0.state != stateError {
141+ c0 = joinRange(c0, e.rangeContext)
142+ }
143+ e.rangeContext = e.rangeContext.outer
144+ if c0.state == stateError {
145+ return c0
146+ }
147+
148 // The "true" branch of a "range" node can execute multiple times.
149 // We check that executing n.List once results in the same context
150 // as executing n.List twice.
151+ e.rangeContext = &rangeContext{outer: e.rangeContext}
152 c1, _ := e.escapeListConditionally(c0, n.List, nil)
153 c0 = join(c0, c1, n, nodeName)
154 if c0.state == stateError {
155+ e.rangeContext = e.rangeContext.outer
156 // Make clear that this is a problem on loop re-entry
157 // since developers tend to overlook that branch when
158 // debugging templates.
159@@ -481,11 +518,39 @@ func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string)
160 c0.err.Description = "on range loop re-entry: " + c0.err.Description
161 return c0
162 }
163+ c0 = joinRange(c0, e.rangeContext)
164+ e.rangeContext = e.rangeContext.outer
165+ if c0.state == stateError {
166+ return c0
167+ }
168 }
169 c1 := e.escapeList(c, n.ElseList)
170 return join(c0, c1, n, nodeName)
171 }
172
173+func joinRange(c0 context, rc *rangeContext) context {
174+ // Merge contexts at break and continue statements into overall body context.
175+ // In theory we could treat breaks differently from continues, but for now it is
176+ // enough to treat them both as going back to the start of the loop (which may then stop).
177+ for _, c := range rc.breaks {
178+ c0 = join(c0, c, c.n, "range")
179+ if c0.state == stateError {
180+ c0.err.Line = c.n.(*parse.BreakNode).Line
181+ c0.err.Description = "at range loop break: " + c0.err.Description
182+ return c0
183+ }
184+ }
185+ for _, c := range rc.continues {
186+ c0 = join(c0, c, c.n, "range")
187+ if c0.state == stateError {
188+ c0.err.Line = c.n.(*parse.ContinueNode).Line
189+ c0.err.Description = "at range loop continue: " + c0.err.Description
190+ return c0
191+ }
192+ }
193+ return c0
194+}
195+
196 // escapeList escapes a list template node.
197 func (e *escaper) escapeList(c context, n *parse.ListNode) context {
198 if n == nil {
199@@ -493,6 +558,9 @@ func (e *escaper) escapeList(c context, n *parse.ListNode) context {
200 }
201 for _, m := range n.Nodes {
202 c = e.escape(c, m)
203+ if c.state == stateDead {
204+ break
205+ }
206 }
207 return c
208 }
209@@ -503,6 +571,7 @@ func (e *escaper) escapeList(c context, n *parse.ListNode) context {
210 // which is the same as whether e was updated.
211 func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter func(*escaper, context) bool) (context, bool) {
212 e1 := makeEscaper(e.ns)
213+ e1.rangeContext = e.rangeContext
214 // Make type inferences available to f.
215 for k, v := range e.output {
216 e1.output[k] = v
217diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
218index c709660..fa2b84a 100644
219--- a/src/html/template/escape_test.go
220+++ b/src/html/template/escape_test.go
221@@ -920,6 +920,22 @@ func TestErrors(t *testing.T) {
222 "<a href='/foo?{{range .Items}}&{{.K}}={{.V}}{{end}}'>",
223 "",
224 },
225+ {
226+ "{{range .Items}}<a{{if .X}}{{end}}>{{end}}",
227+ "",
228+ },
229+ {
230+ "{{range .Items}}<a{{if .X}}{{end}}>{{continue}}{{end}}",
231+ "",
232+ },
233+ {
234+ "{{range .Items}}<a{{if .X}}{{end}}>{{break}}{{end}}",
235+ "",
236+ },
237+ {
238+ "{{range .Items}}<a{{if .X}}{{end}}>{{if .X}}{{break}}{{end}}{{end}}",
239+ "",
240+ },
241 // Error cases.
242 {
243 "{{if .Cond}}<a{{end}}",
244@@ -956,6 +972,14 @@ func TestErrors(t *testing.T) {
245 "z:2:8: on range loop re-entry: {{range}} branches",
246 },
247 {
248+ "{{range .Items}}<a{{if .X}}{{break}}{{end}}>{{end}}",
249+ "z:1:29: at range loop break: {{range}} branches end in different contexts",
250+ },
251+ {
252+ "{{range .Items}}<a{{if .X}}{{continue}}{{end}}>{{end}}",
253+ "z:1:29: at range loop continue: {{range}} branches end in different contexts",
254+ },
255+ {
256 "<a b=1 c={{.H}}",
257 "z: ends in a non-text context: {stateAttr delimSpaceOrTagEnd",
258 },
259diff --git a/src/text/template/doc.go b/src/text/template/doc.go
260index 7b30294..0228b15 100644
261--- a/src/text/template/doc.go
262+++ b/src/text/template/doc.go
263@@ -112,6 +112,14 @@ data, defined in detail in the corresponding sections that follow.
264 T0 is executed; otherwise, dot is set to the successive elements
265 of the array, slice, or map and T1 is executed.
266
267+ {{break}}
268+ The innermost {{range pipeline}} loop is ended early, stopping the
269+ current iteration and bypassing all remaining iterations.
270+
271+ {{continue}}
272+ The current iteration of the innermost {{range pipeline}} loop is
273+ stopped, and the loop starts the next iteration.
274+
275 {{template "name"}}
276 The template with the specified name is executed with nil data.
277
278diff --git a/src/text/template/exec.go b/src/text/template/exec.go
279index 7ac5175..6cb140a 100644
280--- a/src/text/template/exec.go
281+++ b/src/text/template/exec.go
282@@ -5,6 +5,7 @@
283 package template
284
285 import (
286+ "errors"
287 "fmt"
288 "internal/fmtsort"
289 "io"
290@@ -244,6 +245,12 @@ func (t *Template) DefinedTemplates() string {
291 return b.String()
292 }
293
294+// Sentinel errors for use with panic to signal early exits from range loops.
295+var (
296+ walkBreak = errors.New("break")
297+ walkContinue = errors.New("continue")
298+)
299+
300 // Walk functions step through the major pieces of the template structure,
301 // generating output as they go.
302 func (s *state) walk(dot reflect.Value, node parse.Node) {
303@@ -256,7 +263,11 @@ func (s *state) walk(dot reflect.Value, node parse.Node) {
304 if len(node.Pipe.Decl) == 0 {
305 s.printValue(node, val)
306 }
307+ case *parse.BreakNode:
308+ panic(walkBreak)
309 case *parse.CommentNode:
310+ case *parse.ContinueNode:
311+ panic(walkContinue)
312 case *parse.IfNode:
313 s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList)
314 case *parse.ListNode:
315@@ -335,6 +346,11 @@ func isTrue(val reflect.Value) (truth, ok bool) {
316
317 func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
318 s.at(r)
319+ defer func() {
320+ if r := recover(); r != nil && r != walkBreak {
321+ panic(r)
322+ }
323+ }()
324 defer s.pop(s.mark())
325 val, _ := indirect(s.evalPipeline(dot, r.Pipe))
326 // mark top of stack before any variables in the body are pushed.
327@@ -348,8 +364,14 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
328 if len(r.Pipe.Decl) > 1 {
329 s.setTopVar(2, index)
330 }
331+ defer s.pop(mark)
332+ defer func() {
333+ // Consume panic(walkContinue)
334+ if r := recover(); r != nil && r != walkContinue {
335+ panic(r)
336+ }
337+ }()
338 s.walk(elem, r.List)
339- s.pop(mark)
340 }
341 switch val.Kind() {
342 case reflect.Array, reflect.Slice:
343diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
344index 3309b33..a639f44 100644
345--- a/src/text/template/exec_test.go
346+++ b/src/text/template/exec_test.go
347@@ -563,6 +563,8 @@ var execTests = []execTest{
348 {"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", tVal, true},
349 {"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true},
350 {"range empty else", "{{range .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
351+ {"range []int break else", "{{range .SI}}-{{.}}-{{break}}NOTREACHED{{else}}EMPTY{{end}}", "-3-", tVal, true},
352+ {"range []int continue else", "{{range .SI}}-{{.}}-{{continue}}NOTREACHED{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true},
353 {"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", tVal, true},
354 {"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", "-20--21--22-", tVal, true},
355 {"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, true},
356diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
357index 6784071..95e3377 100644
358--- a/src/text/template/parse/lex.go
359+++ b/src/text/template/parse/lex.go
360@@ -62,6 +62,8 @@ const (
361 // Keywords appear after all the rest.
362 itemKeyword // used only to delimit the keywords
363 itemBlock // block keyword
364+ itemBreak // break keyword
365+ itemContinue // continue keyword
366 itemDot // the cursor, spelled '.'
367 itemDefine // define keyword
368 itemElse // else keyword
369@@ -76,6 +78,8 @@ const (
370 var key = map[string]itemType{
371 ".": itemDot,
372 "block": itemBlock,
373+ "break": itemBreak,
374+ "continue": itemContinue,
375 "define": itemDefine,
376 "else": itemElse,
377 "end": itemEnd,
378@@ -119,6 +123,8 @@ type lexer struct {
379 parenDepth int // nesting depth of ( ) exprs
380 line int // 1+number of newlines seen
381 startLine int // start line of this item
382+ breakOK bool // break keyword allowed
383+ continueOK bool // continue keyword allowed
384 }
385
386 // next returns the next rune in the input.
387@@ -461,7 +467,12 @@ Loop:
388 }
389 switch {
390 case key[word] > itemKeyword:
391- l.emit(key[word])
392+ item := key[word]
393+ if item == itemBreak && !l.breakOK || item == itemContinue && !l.continueOK {
394+ l.emit(itemIdentifier)
395+ } else {
396+ l.emit(item)
397+ }
398 case word[0] == '.':
399 l.emit(itemField)
400 case word == "true", word == "false":
401diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
402index 6510eed..df6aabf 100644
403--- a/src/text/template/parse/lex_test.go
404+++ b/src/text/template/parse/lex_test.go
405@@ -35,6 +35,8 @@ var itemName = map[itemType]string{
406 // keywords
407 itemDot: ".",
408 itemBlock: "block",
409+ itemBreak: "break",
410+ itemContinue: "continue",
411 itemDefine: "define",
412 itemElse: "else",
413 itemIf: "if",
414diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go
415index a9dad5e..c398da0 100644
416--- a/src/text/template/parse/node.go
417+++ b/src/text/template/parse/node.go
418@@ -71,6 +71,8 @@ const (
419 NodeVariable // A $ variable.
420 NodeWith // A with action.
421 NodeComment // A comment.
422+ NodeBreak // A break action.
423+ NodeContinue // A continue action.
424 )
425
426 // Nodes.
427@@ -907,6 +909,40 @@ func (i *IfNode) Copy() Node {
428 return i.tr.newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList())
429 }
430
431+// BreakNode represents a {{break}} action.
432+type BreakNode struct {
433+ tr *Tree
434+ NodeType
435+ Pos
436+ Line int
437+}
438+
439+func (t *Tree) newBreak(pos Pos, line int) *BreakNode {
440+ return &BreakNode{tr: t, NodeType: NodeBreak, Pos: pos, Line: line}
441+}
442+
443+func (b *BreakNode) Copy() Node { return b.tr.newBreak(b.Pos, b.Line) }
444+func (b *BreakNode) String() string { return "{{break}}" }
445+func (b *BreakNode) tree() *Tree { return b.tr }
446+func (b *BreakNode) writeTo(sb *strings.Builder) { sb.WriteString("{{break}}") }
447+
448+// ContinueNode represents a {{continue}} action.
449+type ContinueNode struct {
450+ tr *Tree
451+ NodeType
452+ Pos
453+ Line int
454+}
455+
456+func (t *Tree) newContinue(pos Pos, line int) *ContinueNode {
457+ return &ContinueNode{tr: t, NodeType: NodeContinue, Pos: pos, Line: line}
458+}
459+
460+func (c *ContinueNode) Copy() Node { return c.tr.newContinue(c.Pos, c.Line) }
461+func (c *ContinueNode) String() string { return "{{continue}}" }
462+func (c *ContinueNode) tree() *Tree { return c.tr }
463+func (c *ContinueNode) writeTo(sb *strings.Builder) { sb.WriteString("{{continue}}") }
464+
465 // RangeNode represents a {{range}} action and its commands.
466 type RangeNode struct {
467 BranchNode
468diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
469index 5e6e512..7f78b56 100644
470--- a/src/text/template/parse/parse.go
471+++ b/src/text/template/parse/parse.go
472@@ -31,6 +31,7 @@ type Tree struct {
473 vars []string // variables defined at the moment.
474 treeSet map[string]*Tree
475 actionLine int // line of left delim starting action
476+ rangeDepth int
477 mode Mode
478 }
479
480@@ -223,6 +224,8 @@ func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer, treeSet ma
481 t.vars = []string{"$"}
482 t.funcs = funcs
483 t.treeSet = treeSet
484+ lex.breakOK = !t.hasFunction("break")
485+ lex.continueOK = !t.hasFunction("continue")
486 }
487
488 // stopParse terminates parsing.
489@@ -385,6 +388,10 @@ func (t *Tree) action() (n Node) {
490 switch token := t.nextNonSpace(); token.typ {
491 case itemBlock:
492 return t.blockControl()
493+ case itemBreak:
494+ return t.breakControl(token.pos, token.line)
495+ case itemContinue:
496+ return t.continueControl(token.pos, token.line)
497 case itemElse:
498 return t.elseControl()
499 case itemEnd:
500@@ -404,6 +411,32 @@ func (t *Tree) action() (n Node) {
501 return t.newAction(token.pos, token.line, t.pipeline("command", itemRightDelim))
502 }
503
504+// Break:
505+// {{break}}
506+// Break keyword is past.
507+func (t *Tree) breakControl(pos Pos, line int) Node {
508+ if token := t.next(); token.typ != itemRightDelim {
509+ t.unexpected(token, "in {{break}}")
510+ }
511+ if t.rangeDepth == 0 {
512+ t.errorf("{{break}} outside {{range}}")
513+ }
514+ return t.newBreak(pos, line)
515+}
516+
517+// Continue:
518+// {{continue}}
519+// Continue keyword is past.
520+func (t *Tree) continueControl(pos Pos, line int) Node {
521+ if token := t.next(); token.typ != itemRightDelim {
522+ t.unexpected(token, "in {{continue}}")
523+ }
524+ if t.rangeDepth == 0 {
525+ t.errorf("{{continue}} outside {{range}}")
526+ }
527+ return t.newContinue(pos, line)
528+}
529+
530 // Pipeline:
531 // declarations? command ('|' command)*
532 func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) {
533@@ -479,8 +512,14 @@ func (t *Tree) checkPipeline(pipe *PipeNode, context string) {
534 func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) {
535 defer t.popVars(len(t.vars))
536 pipe = t.pipeline(context, itemRightDelim)
537+ if context == "range" {
538+ t.rangeDepth++
539+ }
540 var next Node
541 list, next = t.itemList()
542+ if context == "range" {
543+ t.rangeDepth--
544+ }
545 switch next.Type() {
546 case nodeEnd: //done
547 case nodeElse:
548@@ -522,7 +561,8 @@ func (t *Tree) ifControl() Node {
549 // {{range pipeline}} itemList {{else}} itemList {{end}}
550 // Range keyword is past.
551 func (t *Tree) rangeControl() Node {
552- return t.newRange(t.parseControl(false, "range"))
553+ r := t.newRange(t.parseControl(false, "range"))
554+ return r
555 }
556
557 // With:
558diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
559index 220f984..ba45636 100644
560--- a/src/text/template/parse/parse_test.go
561+++ b/src/text/template/parse/parse_test.go
562@@ -230,6 +230,10 @@ var parseTests = []parseTest{
563 `{{range $x := .SI}}{{.}}{{end}}`},
564 {"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError,
565 `{{range $x, $y := .SI}}{{.}}{{end}}`},
566+ {"range with break", "{{range .SI}}{{.}}{{break}}{{end}}", noError,
567+ `{{range .SI}}{{.}}{{break}}{{end}}`},
568+ {"range with continue", "{{range .SI}}{{.}}{{continue}}{{end}}", noError,
569+ `{{range .SI}}{{.}}{{continue}}{{end}}`},
570 {"constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", noError,
571 `{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`},
572 {"template", "{{template `x`}}", noError,
573@@ -279,6 +283,10 @@ var parseTests = []parseTest{
574 {"adjacent args", "{{printf 3`x`}}", hasError, ""},
575 {"adjacent args with .", "{{printf `x`.}}", hasError, ""},
576 {"extra end after if", "{{if .X}}a{{else if .Y}}b{{end}}{{end}}", hasError, ""},
577+ {"break outside range", "{{range .}}{{end}} {{break}}", hasError, ""},
578+ {"continue outside range", "{{range .}}{{end}} {{continue}}", hasError, ""},
579+ {"break in range else", "{{range .}}{{else}}{{break}}{{end}}", hasError, ""},
580+ {"continue in range else", "{{range .}}{{else}}{{continue}}{{end}}", hasError, ""},
581 // Other kinds of assignments and operators aren't available yet.
582 {"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"},
583 {"bug0b", "{{$x += 1}}{{$x}}", hasError, ""},
584--
5852.7.4
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-3.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_6.patch
index d5bb33e091..baf400b891 100644
--- a/meta/recipes-devtools/go/go-1.14/CVE-2023-24538-3.patch
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_6.patch
@@ -1,7 +1,7 @@
1From 16f4882984569f179d73967c9eee679bb9b098c5 Mon Sep 17 00:00:00 2001 1From 16f4882984569f179d73967c9eee679bb9b098c5 Mon Sep 17 00:00:00 2001
2From: Roland Shoemaker <bracewell@google.com> 2From: Roland Shoemaker <bracewell@google.com>
3Date: Mon, 20 Mar 2023 11:01:13 -0700 3Date: Mon, 20 Mar 2023 11:01:13 -0700
4Subject: [PATCH 3/3] html/template: disallow actions in JS template literals 4Subject: [PATCH 6/6] html/template: disallow actions in JS template literals
5 5
6ECMAScript 6 introduced template literals[0][1] which are delimited with 6ECMAScript 6 introduced template literals[0][1] which are delimited with
7backticks. These need to be escaped in a similar fashion to the 7backticks. These need to be escaped in a similar fashion to the
@@ -52,12 +52,15 @@ CVE: CVE-2023-24538
52Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> 52Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
53--- 53---
54 src/html/template/context.go | 2 ++ 54 src/html/template/context.go | 2 ++
55 src/html/template/error.go | 13 +++++++++++++ 55 src/html/template/error.go | 13 ++++++++
56 src/html/template/escape.go | 11 +++++++++++ 56 src/html/template/escape.go | 11 +++++++
57 src/html/template/escape_test.go | 66 ++++++++++++++++++++++-----------------
57 src/html/template/js.go | 2 ++ 58 src/html/template/js.go | 2 ++
58 src/html/template/jsctx_string.go | 9 +++++++++ 59 src/html/template/js_test.go | 2 +-
59 src/html/template/transition.go | 7 ++++++- 60 src/html/template/jsctx_string.go | 9 ++++++
60 6 files changed, 43 insertions(+), 1 deletion(-) 61 src/html/template/state_string.go | 37 ++++++++++++++++++++--
62 src/html/template/transition.go | 7 ++++-
63 9 files changed, 116 insertions(+), 33 deletions(-)
61 64
62diff --git a/src/html/template/context.go b/src/html/template/context.go 65diff --git a/src/html/template/context.go b/src/html/template/context.go
63index f7d4849..0b65313 100644 66index f7d4849..0b65313 100644
@@ -125,6 +128,104 @@ index f12dafa..29ca5b3 100644
125 case stateJSRegexp: 128 case stateJSRegexp:
126 s = append(s, "_html_template_jsregexpescaper") 129 s = append(s, "_html_template_jsregexpescaper")
127 case stateCSS: 130 case stateCSS:
131diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
132index fa2b84a..1b150e9 100644
133--- a/src/html/template/escape_test.go
134+++ b/src/html/template/escape_test.go
135@@ -681,35 +681,31 @@ func TestEscape(t *testing.T) {
136 }
137
138 for _, test := range tests {
139- tmpl := New(test.name)
140- tmpl = Must(tmpl.Parse(test.input))
141- // Check for bug 6459: Tree field was not set in Parse.
142- if tmpl.Tree != tmpl.text.Tree {
143- t.Errorf("%s: tree not set properly", test.name)
144- continue
145- }
146- b := new(bytes.Buffer)
147- if err := tmpl.Execute(b, data); err != nil {
148- t.Errorf("%s: template execution failed: %s", test.name, err)
149- continue
150- }
151- if w, g := test.output, b.String(); w != g {
152- t.Errorf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g)
153- continue
154- }
155- b.Reset()
156- if err := tmpl.Execute(b, pdata); err != nil {
157- t.Errorf("%s: template execution failed for pointer: %s", test.name, err)
158- continue
159- }
160- if w, g := test.output, b.String(); w != g {
161- t.Errorf("%s: escaped output for pointer: want\n\t%q\ngot\n\t%q", test.name, w, g)
162- continue
163- }
164- if tmpl.Tree != tmpl.text.Tree {
165- t.Errorf("%s: tree mismatch", test.name)
166- continue
167- }
168+ t.Run(test.name, func(t *testing.T) {
169+ tmpl := New(test.name)
170+ tmpl = Must(tmpl.Parse(test.input))
171+ // Check for bug 6459: Tree field was not set in Parse.
172+ if tmpl.Tree != tmpl.text.Tree {
173+ t.Fatalf("%s: tree not set properly", test.name)
174+ }
175+ b := new(strings.Builder)
176+ if err := tmpl.Execute(b, data); err != nil {
177+ t.Fatalf("%s: template execution failed: %s", test.name, err)
178+ }
179+ if w, g := test.output, b.String(); w != g {
180+ t.Fatalf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g)
181+ }
182+ b.Reset()
183+ if err := tmpl.Execute(b, pdata); err != nil {
184+ t.Fatalf("%s: template execution failed for pointer: %s", test.name, err)
185+ }
186+ if w, g := test.output, b.String(); w != g {
187+ t.Fatalf("%s: escaped output for pointer: want\n\t%q\ngot\n\t%q", test.name, w, g)
188+ }
189+ if tmpl.Tree != tmpl.text.Tree {
190+ t.Fatalf("%s: tree mismatch", test.name)
191+ }
192+ })
193 }
194 }
195
196@@ -936,6 +932,10 @@ func TestErrors(t *testing.T) {
197 "{{range .Items}}<a{{if .X}}{{end}}>{{if .X}}{{break}}{{end}}{{end}}",
198 "",
199 },
200+ {
201+ "<script>var a = `${a+b}`</script>`",
202+ "",
203+ },
204 // Error cases.
205 {
206 "{{if .Cond}}<a{{end}}",
207@@ -1082,6 +1082,10 @@ func TestErrors(t *testing.T) {
208 // html is allowed since it is the last command in the pipeline, but urlquery is not.
209 `predefined escaper "urlquery" disallowed in template`,
210 },
211+ {
212+ "<script>var tmpl = `asd {{.}}`;</script>",
213+ `{{.}} appears in a JS template literal`,
214+ },
215 }
216 for _, test := range tests {
217 buf := new(bytes.Buffer)
218@@ -1304,6 +1308,10 @@ func TestEscapeText(t *testing.T) {
219 context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript},
220 },
221 {
222+ "<a onclick=\"`foo",
223+ context{state: stateJSBqStr, delim: delimDoubleQuote, attr: attrScript},
224+ },
225+ {
226 `<A ONCLICK="'`,
227 context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript},
228 },
128diff --git a/src/html/template/js.go b/src/html/template/js.go 229diff --git a/src/html/template/js.go b/src/html/template/js.go
129index ea9c183..b888eaf 100644 230index ea9c183..b888eaf 100644
130--- a/src/html/template/js.go 231--- a/src/html/template/js.go
@@ -145,6 +246,19 @@ index ea9c183..b888eaf 100644
145 '+': `\u002b`, 246 '+': `\u002b`,
146 '/': `\/`, 247 '/': `\/`,
147 '<': `\u003c`, 248 '<': `\u003c`,
249diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go
250index d7ee47b..7d963ae 100644
251--- a/src/html/template/js_test.go
252+++ b/src/html/template/js_test.go
253@@ -292,7 +292,7 @@ func TestEscapersOnLower7AndSelectHighCodepoints(t *testing.T) {
254 `0123456789:;\u003c=\u003e?` +
255 `@ABCDEFGHIJKLMNO` +
256 `PQRSTUVWXYZ[\\]^_` +
257- "`abcdefghijklmno" +
258+ "\\u0060abcdefghijklmno" +
259 "pqrstuvwxyz{|}~\u007f" +
260 "\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E",
261 },
148diff --git a/src/html/template/jsctx_string.go b/src/html/template/jsctx_string.go 262diff --git a/src/html/template/jsctx_string.go b/src/html/template/jsctx_string.go
149index dd1d87e..2394893 100644 263index dd1d87e..2394893 100644
150--- a/src/html/template/jsctx_string.go 264--- a/src/html/template/jsctx_string.go
@@ -165,6 +279,55 @@ index dd1d87e..2394893 100644
165 const _jsCtx_name = "jsCtxRegexpjsCtxDivOpjsCtxUnknown" 279 const _jsCtx_name = "jsCtxRegexpjsCtxDivOpjsCtxUnknown"
166 280
167 var _jsCtx_index = [...]uint8{0, 11, 21, 33} 281 var _jsCtx_index = [...]uint8{0, 11, 21, 33}
282diff --git a/src/html/template/state_string.go b/src/html/template/state_string.go
283index 05104be..6fb1a6e 100644
284--- a/src/html/template/state_string.go
285+++ b/src/html/template/state_string.go
286@@ -4,9 +4,42 @@ package template
287
288 import "strconv"
289
290-const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError"
291+func _() {
292+ // An "invalid array index" compiler error signifies that the constant values have changed.
293+ // Re-run the stringer command to generate them again.
294+ var x [1]struct{}
295+ _ = x[stateText-0]
296+ _ = x[stateTag-1]
297+ _ = x[stateAttrName-2]
298+ _ = x[stateAfterName-3]
299+ _ = x[stateBeforeValue-4]
300+ _ = x[stateHTMLCmt-5]
301+ _ = x[stateRCDATA-6]
302+ _ = x[stateAttr-7]
303+ _ = x[stateURL-8]
304+ _ = x[stateSrcset-9]
305+ _ = x[stateJS-10]
306+ _ = x[stateJSDqStr-11]
307+ _ = x[stateJSSqStr-12]
308+ _ = x[stateJSBqStr-13]
309+ _ = x[stateJSRegexp-14]
310+ _ = x[stateJSBlockCmt-15]
311+ _ = x[stateJSLineCmt-16]
312+ _ = x[stateCSS-17]
313+ _ = x[stateCSSDqStr-18]
314+ _ = x[stateCSSSqStr-19]
315+ _ = x[stateCSSDqURL-20]
316+ _ = x[stateCSSSqURL-21]
317+ _ = x[stateCSSURL-22]
318+ _ = x[stateCSSBlockCmt-23]
319+ _ = x[stateCSSLineCmt-24]
320+ _ = x[stateError-25]
321+ _ = x[stateDead-26]
322+}
323+
324+const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
325
326-var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 155, 170, 184, 192, 205, 218, 231, 244, 255, 271, 286, 296}
327+var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 204, 217, 230, 243, 256, 267, 283, 298, 308, 317}
328
329 func (i state) String() string {
330 if i >= state(len(_state_index)-1) {
168diff --git a/src/html/template/transition.go b/src/html/template/transition.go 331diff --git a/src/html/template/transition.go b/src/html/template/transition.go
169index 06df679..92eb351 100644 332index 06df679..92eb351 100644
170--- a/src/html/template/transition.go 333--- a/src/html/template/transition.go
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-39318.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-39318.patch
index 20e70c0485..00def8fcda 100644
--- a/meta/recipes-devtools/go/go-1.14/CVE-2023-39318.patch
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-39318.patch
@@ -34,9 +34,9 @@ Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
34 src/html/template/context.go | 6 ++- 34 src/html/template/context.go | 6 ++-
35 src/html/template/escape.go | 5 +- 35 src/html/template/escape.go | 5 +-
36 src/html/template/escape_test.go | 10 ++++ 36 src/html/template/escape_test.go | 10 ++++
37 src/html/template/state_string.go | 4 +- 37 src/html/template/state_string.go | 26 +++++-----
38 src/html/template/transition.go | 80 ++++++++++++++++++++----------- 38 src/html/template/transition.go | 80 ++++++++++++++++++++-----------
39 5 files changed, 72 insertions(+), 33 deletions(-) 39 5 files changed, 84 insertions(+), 43 deletions(-)
40 40
41diff --git a/src/html/template/context.go b/src/html/template/context.go 41diff --git a/src/html/template/context.go b/src/html/template/context.go
42index 0b65313..4eb7891 100644 42index 0b65313..4eb7891 100644
@@ -105,14 +105,38 @@ diff --git a/src/html/template/state_string.go b/src/html/template/state_string.
105index 05104be..b5cfe70 100644 105index 05104be..b5cfe70 100644
106--- a/src/html/template/state_string.go 106--- a/src/html/template/state_string.go
107+++ b/src/html/template/state_string.go 107+++ b/src/html/template/state_string.go
108@@ -4,9 +4,9 @@ package template 108@@ -25,21 +25,23 @@ func _() {
109 109 _ = x[stateJSRegexp-14]
110 import "strconv" 110 _ = x[stateJSBlockCmt-15]
111 _ = x[stateJSLineCmt-16]
112- _ = x[stateCSS-17]
113- _ = x[stateCSSDqStr-18]
114- _ = x[stateCSSSqStr-19]
115- _ = x[stateCSSDqURL-20]
116- _ = x[stateCSSSqURL-21]
117- _ = x[stateCSSURL-22]
118- _ = x[stateCSSBlockCmt-23]
119- _ = x[stateCSSLineCmt-24]
120- _ = x[stateError-25]
121- _ = x[stateDead-26]
122+ _ = x[stateJSHTMLOpenCmt-17]
123+ _ = x[stateJSHTMLCloseCmt-18]
124+ _ = x[stateCSS-19]
125+ _ = x[stateCSSDqStr-20]
126+ _ = x[stateCSSSqStr-21]
127+ _ = x[stateCSSDqURL-22]
128+ _ = x[stateCSSSqURL-23]
129+ _ = x[stateCSSURL-24]
130+ _ = x[stateCSSBlockCmt-25]
131+ _ = x[stateCSSLineCmt-26]
132+ _ = x[stateError-27]
133+ _ = x[stateDead-28]
134 }
111 135
112-const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError" 136-const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
113+const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" 137+const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
114 138
115-var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 155, 170, 184, 192, 205, 218, 231, 244, 255, 271, 286, 296} 139-var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 204, 217, 230, 243, 256, 267, 283, 298, 308, 317}
116+var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 214, 233, 241, 254, 267, 280, 293, 304, 320, 335, 345, 354} 140+var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 214, 233, 241, 254, 267, 280, 293, 304, 320, 335, 345, 354}
117 141
118 func (i state) String() string { 142 func (i state) String() string {