On Fri, Sep 29, 2023 at 9:20 AM Steve Sakoman <st...@sakoman.com> wrote: > > On Fri, Sep 29, 2023 at 9:06 AM Shubham Kulkarni <skulka...@mvista.com> wrote: > > > > Hi Steve, > > > > Can you please check, if you are able to get these patches I sent for the > > Kirkstone & Dunfell branch. > > It is not generating the group links/Topic id links like > > https://lists.openembedded.org/g/openembedded-devel/message/. > > > > I have sent a v2 version for both the dunfell and kirkstone, but still it > > didn't generate the links. > > If you are able to get these patches, you can take either original or v2 > > for both Dunfell and Kirkstone. Both v1 & v2 are the same, just resent for > > link generation. Apologies for the inconvenience caused. > > No, I'm not seeing these on the list :-(
Actually the kirsktone arrived just after sent this email! Steve > > On Sat, Sep 30, 2023 at 12:23 AM Shubham Kulkarni <skulka...@mvista.com> > > wrote: > >> > >> From: Shubham Kulkarni <skulka...@mvista.com> > >> > >> 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 > >> > >> Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> --- > >> meta/recipes-devtools/go/go-1.14.inc | 5 +- > >> .../go/go-1.14/CVE-2023-24538-1.patch | 4 +- > >> .../go/go-1.14/CVE-2023-24538-2.patch | 447 ++++++++++++- > >> .../go/go-1.14/CVE-2023-24538_3.patch | 393 ++++++++++++ > >> .../go/go-1.14/CVE-2023-24538_4.patch | 497 +++++++++++++++ > >> .../go/go-1.14/CVE-2023-24538_5.patch | 585 ++++++++++++++++++ > >> ...3-24538-3.patch => CVE-2023-24538_6.patch} | 175 +++++- > >> .../go/go-1.14/CVE-2023-39318.patch | 38 +- > >> 8 files changed, 2124 insertions(+), 20 deletions(-) > >> create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch > >> create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch > >> create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2023-24538_5.patch > >> rename meta/recipes-devtools/go/go-1.14/{CVE-2023-24538-3.patch => > >> CVE-2023-24538_6.patch} (53%) > >> > >> 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 += "\ > >> file://CVE-2023-24534.patch \ > >> file://CVE-2023-24538-1.patch \ > >> file://CVE-2023-24538-2.patch \ > >> - file://CVE-2023-24538-3.patch \ > >> + file://CVE-2023-24538_3.patch \ > >> + file://CVE-2023-24538_4.patch \ > >> + file://CVE-2023-24538_5.patch \ > >> + file://CVE-2023-24538_6.patch \ > >> file://CVE-2023-24539.patch \ > >> file://CVE-2023-24540.patch \ > >> 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 @@ > >> From 8acd01094d9ee17f6e763a61e49a8a808b3a9ddb Mon Sep 17 00:00:00 2001 > >> From: Brad Fitzpatrick <bradf...@golang.org> > >> Date: Mon, 2 Aug 2021 14:55:51 -0700 > >> -Subject: [PATCH 1/3] net/netip: add new IP address package > >> +Subject: [PATCH 1/6] net/netip: add new IP address package > >> > >> Co-authored-by: Alex Willmer <a...@moreati.org.uk> (GitHub @moreati) > >> Co-authored-by: Alexander Yastrebov <yastrebov.a...@gmail.com> > >> @@ -31,7 +31,7 @@ Trust: Brad Fitzpatrick <bradf...@golang.org> > >> > >> Dependency Patch #1 > >> > >> -Upstream-Status: Backport > >> [https://github.com/golang/go/commit/a59e33224e42d60a97fa720a45e1b74eb6aaa3d0] > >> +Upstream-Status: Backport from > >> https://github.com/golang/go/commit/a59e33224e42d60a97fa720a45e1b74eb6aaa3d0 > >> CVE: CVE-2023-24538 > >> Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> --- > >> 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..3840617a32 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 @@ > >> From 6fc21505614f36178df0dad7034b6b8e3f7588d5 Mon Sep 17 00:00:00 2001 > >> From: empijei <robcl...@gmail.com> > >> Date: Fri, 27 Mar 2020 19:27:55 +0100 > >> -Subject: [PATCH 2/3] html/template,text/template: switch to Unicode > >> escapes > >> +Subject: [PATCH 2/6] html/template,text/template: switch to Unicode > >> escapes > >> for JSON compatibility > >> MIME-Version: 1.0 > >> Content-Type: text/plain; charset=UTF-8 > >> @@ -31,10 +31,238 @@ Upstream-Status: Backport from > >> https://github.com/golang/go/commit/d4d298040d072 > >> CVE: CVE-2023-24538 > >> Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> --- > >> - src/html/template/js.go | 70 > >> +++++++++++++++++++++++++++------------------- > >> - src/text/template/funcs.go | 8 +++--- > >> - 2 files changed, 46 insertions(+), 32 deletions(-) > >> + src/html/template/content_test.go | 70 > >> +++++++++++++++++++------------------- > >> + src/html/template/escape_test.go | 6 ++-- > >> + src/html/template/example_test.go | 6 ++-- > >> + src/html/template/js.go | 70 > >> +++++++++++++++++++++++--------------- > >> + src/html/template/js_test.go | 68 > >> ++++++++++++++++++------------------ > >> + src/html/template/template_test.go | 39 +++++++++++++++++++++ > >> + src/text/template/exec_test.go | 6 ++-- > >> + src/text/template/funcs.go | 8 ++--- > >> + 8 files changed, 163 insertions(+), 110 deletions(-) > >> > >> +diff --git a/src/html/template/content_test.go > >> b/src/html/template/content_test.go > >> +index 72d56f5..bd86527 100644 > >> +--- a/src/html/template/content_test.go > >> ++++ b/src/html/template/content_test.go > >> +@@ -18,7 +18,7 @@ func TestTypedContent(t *testing.T) { > >> + HTML(`Hello, <b>World</b> &tc!`), > >> + HTMLAttr(` dir="ltr"`), > >> + JS(`c && alert("Hello, World!");`), > >> +- JSStr(`Hello, World & O'Reilly\x21`), > >> ++ JSStr(`Hello, World & O'Reilly\u0021`), > >> + URL(`greeting=H%69,&addressee=(World)`), > >> + Srcset(`greeting=H%69,&addressee=(World) 2x, > >> https://golang.org/favicon.ico 500.5w`), > >> + URL(`,foo/,`), > >> +@@ -70,7 +70,7 @@ func TestTypedContent(t *testing.T) { > >> + `Hello, <b>World</b> &tc!`, > >> + ` dir="ltr"`, > >> + `c && alert("Hello, > >> World!");`, > >> +- `Hello, World & O'Reilly\x21`, > >> ++ `Hello, World & O'Reilly\u0021`, > >> + `greeting=H%69,&addressee=(World)`, > >> + `greeting=H%69,&addressee=(World) 2x, > >> https://golang.org/favicon.ico 500.5w`, > >> + `,foo/,`, > >> +@@ -100,7 +100,7 @@ func TestTypedContent(t *testing.T) { > >> + `Hello, World &tc!`, > >> + ` dir="ltr"`, > >> + > >> `c && alert("Hello, World!");`, > >> +- > >> `Hello, World & O'Reilly\x21`, > >> ++ > >> `Hello, World & O'Reilly\u0021`, > >> + > >> `greeting=H%69,&addressee=(World)`, > >> + > >> `greeting=H%69,&addressee=(World) 2x, https://golang.org/favicon.ico 500.5w`, > >> + `,foo/,`, > >> +@@ -115,7 +115,7 @@ func TestTypedContent(t *testing.T) { > >> + `Hello, World &tc!`, > >> + ` dir="ltr"`, > >> + `c && alert("Hello, > >> World!");`, > >> +- `Hello, World & O'Reilly\x21`, > >> ++ `Hello, World & O'Reilly\u0021`, > >> + `greeting=H%69,&addressee=(World)`, > >> + `greeting=H%69,&addressee=(World) 2x, > >> https://golang.org/favicon.ico 500.5w`, > >> + `,foo/,`, > >> +@@ -130,7 +130,7 @@ func TestTypedContent(t *testing.T) { > >> + `Hello, <b>World</b> &tc!`, > >> + ` dir="ltr"`, > >> + `c && alert("Hello, > >> World!");`, > >> +- `Hello, World & O'Reilly\x21`, > >> ++ `Hello, World & O'Reilly\u0021`, > >> + `greeting=H%69,&addressee=(World)`, > >> + `greeting=H%69,&addressee=(World) 2x, > >> https://golang.org/favicon.ico 500.5w`, > >> + `,foo/,`, > >> +@@ -146,7 +146,7 @@ func TestTypedContent(t *testing.T) { > >> + // Not escaped. > >> + `c && alert("Hello, World!");`, > >> + // Escape sequence not over-escaped. > >> +- `"Hello, World & O'Reilly\x21"`, > >> ++ `"Hello, World & O'Reilly\u0021"`, > >> + `"greeting=H%69,\u0026addressee=(World)"`, > >> + `"greeting=H%69,\u0026addressee=(World) > >> 2x, https://golang.org/favicon.ico 500.5w"`, > >> + `",foo/,"`, > >> +@@ -162,7 +162,7 @@ func TestTypedContent(t *testing.T) { > >> + // Not JS escaped but HTML escaped. > >> + `c && alert("Hello, > >> World!");`, > >> + // Escape sequence not over-escaped. > >> +- `"Hello, World & > >> O'Reilly\x21"`, > >> ++ `"Hello, World & > >> O'Reilly\u0021"`, > >> + > >> `"greeting=H%69,\u0026addressee=(World)"`, > >> + > >> `"greeting=H%69,\u0026addressee=(World) 2x, > >> https://golang.org/favicon.ico 500.5w"`, > >> + `",foo/,"`, > >> +@@ -171,30 +171,30 @@ func TestTypedContent(t *testing.T) { > >> + { > >> + `<script>alert("{{.}}")</script>`, > >> + []string{ > >> +- `\x3cb\x3e \x22foo%\x22 O\x27Reilly > >> \x26bar;`, > >> +- `a[href =~ \x22\/\/example.com\x22]#foo`, > >> +- `Hello, \x3cb\x3eWorld\x3c\/b\x3e > >> \x26amp;tc!`, > >> +- ` dir=\x22ltr\x22`, > >> +- `c \x26\x26 alert(\x22Hello, World!\x22);`, > >> ++ `\u003cb\u003e \u0022foo%\u0022 > >> O\u0027Reilly \u0026bar;`, > >> ++ `a[href =~ > >> \u0022\/\/example.com\u0022]#foo`, > >> ++ `Hello, \u003cb\u003eWorld\u003c\/b\u003e > >> \u0026amp;tc!`, > >> ++ ` dir=\u0022ltr\u0022`, > >> ++ `c \u0026\u0026 alert(\u0022Hello, > >> World!\u0022);`, > >> + // Escape sequence not over-escaped. > >> +- `Hello, World \x26 O\x27Reilly\x21`, > >> +- `greeting=H%69,\x26addressee=(World)`, > >> +- `greeting=H%69,\x26addressee=(World) 2x, > >> https:\/\/golang.org\/favicon.ico 500.5w`, > >> ++ `Hello, World \u0026 O\u0027Reilly\u0021`, > >> ++ `greeting=H%69,\u0026addressee=(World)`, > >> ++ `greeting=H%69,\u0026addressee=(World) 2x, > >> https:\/\/golang.org\/favicon.ico 500.5w`, > >> + `,foo\/,`, > >> + }, > >> + }, > >> + { > >> + `<script > >> type="text/javascript">alert("{{.}}")</script>`, > >> + []string{ > >> +- `\x3cb\x3e \x22foo%\x22 O\x27Reilly > >> \x26bar;`, > >> +- `a[href =~ \x22\/\/example.com\x22]#foo`, > >> +- `Hello, \x3cb\x3eWorld\x3c\/b\x3e > >> \x26amp;tc!`, > >> +- ` dir=\x22ltr\x22`, > >> +- `c \x26\x26 alert(\x22Hello, World!\x22);`, > >> ++ `\u003cb\u003e \u0022foo%\u0022 > >> O\u0027Reilly \u0026bar;`, > >> ++ `a[href =~ > >> \u0022\/\/example.com\u0022]#foo`, > >> ++ `Hello, \u003cb\u003eWorld\u003c\/b\u003e > >> \u0026amp;tc!`, > >> ++ ` dir=\u0022ltr\u0022`, > >> ++ `c \u0026\u0026 alert(\u0022Hello, > >> World!\u0022);`, > >> + // Escape sequence not over-escaped. > >> +- `Hello, World \x26 O\x27Reilly\x21`, > >> +- `greeting=H%69,\x26addressee=(World)`, > >> +- `greeting=H%69,\x26addressee=(World) 2x, > >> https:\/\/golang.org\/favicon.ico 500.5w`, > >> ++ `Hello, World \u0026 O\u0027Reilly\u0021`, > >> ++ `greeting=H%69,\u0026addressee=(World)`, > >> ++ `greeting=H%69,\u0026addressee=(World) 2x, > >> https:\/\/golang.org\/favicon.ico 500.5w`, > >> + `,foo\/,`, > >> + }, > >> + }, > >> +@@ -208,7 +208,7 @@ func TestTypedContent(t *testing.T) { > >> + // Not escaped. > >> + `c && alert("Hello, World!");`, > >> + // Escape sequence not over-escaped. > >> +- `"Hello, World & O'Reilly\x21"`, > >> ++ `"Hello, World & O'Reilly\u0021"`, > >> + `"greeting=H%69,\u0026addressee=(World)"`, > >> + `"greeting=H%69,\u0026addressee=(World) > >> 2x, https://golang.org/favicon.ico 500.5w"`, > >> + `",foo/,"`, > >> +@@ -224,7 +224,7 @@ func TestTypedContent(t *testing.T) { > >> + `Hello, <b>World</b> &tc!`, > >> + ` dir="ltr"`, > >> + `c && alert("Hello, > >> World!");`, > >> +- `Hello, World & O'Reilly\x21`, > >> ++ `Hello, World & O'Reilly\u0021`, > >> + `greeting=H%69,&addressee=(World)`, > >> + `greeting=H%69,&addressee=(World) 2x, > >> https://golang.org/favicon.ico 500.5w`, > >> + `,foo/,`, > >> +@@ -233,15 +233,15 @@ func TestTypedContent(t *testing.T) { > >> + { > >> + `<button onclick='alert("{{.}}")'>`, > >> + []string{ > >> +- `\x3cb\x3e \x22foo%\x22 O\x27Reilly > >> \x26bar;`, > >> +- `a[href =~ \x22\/\/example.com\x22]#foo`, > >> +- `Hello, \x3cb\x3eWorld\x3c\/b\x3e > >> \x26amp;tc!`, > >> +- ` dir=\x22ltr\x22`, > >> +- `c \x26\x26 alert(\x22Hello, World!\x22);`, > >> ++ `\u003cb\u003e \u0022foo%\u0022 > >> O\u0027Reilly \u0026bar;`, > >> ++ `a[href =~ > >> \u0022\/\/example.com\u0022]#foo`, > >> ++ `Hello, \u003cb\u003eWorld\u003c\/b\u003e > >> \u0026amp;tc!`, > >> ++ ` dir=\u0022ltr\u0022`, > >> ++ `c \u0026\u0026 alert(\u0022Hello, > >> World!\u0022);`, > >> + // Escape sequence not over-escaped. > >> +- `Hello, World \x26 O\x27Reilly\x21`, > >> +- `greeting=H%69,\x26addressee=(World)`, > >> +- `greeting=H%69,\x26addressee=(World) 2x, > >> https:\/\/golang.org\/favicon.ico 500.5w`, > >> ++ `Hello, World \u0026 O\u0027Reilly\u0021`, > >> ++ `greeting=H%69,\u0026addressee=(World)`, > >> ++ `greeting=H%69,\u0026addressee=(World) 2x, > >> https:\/\/golang.org\/favicon.ico 500.5w`, > >> + `,foo\/,`, > >> + }, > >> + }, > >> +@@ -253,7 +253,7 @@ func TestTypedContent(t *testing.T) { > >> + > >> `Hello%2c%20%3cb%3eWorld%3c%2fb%3e%20%26amp%3btc%21`, > >> + `%20dir%3d%22ltr%22`, > >> + > >> `c%20%26%26%20alert%28%22Hello%2c%20World%21%22%29%3b`, > >> +- > >> `Hello%2c%20World%20%26%20O%27Reilly%5cx21`, > >> ++ > >> `Hello%2c%20World%20%26%20O%27Reilly%5cu0021`, > >> + // Quotes and parens are escaped but %69 > >> is not over-escaped. HTML escaping is done. > >> + `greeting=H%69,&addressee=%28World%29`, > >> + > >> `greeting%3dH%2569%2c%26addressee%3d%28World%29%202x%2c%20https%3a%2f%2fgolang.org%2ffavicon.ico%20500.5w`, > >> +@@ -268,7 +268,7 @@ func TestTypedContent(t *testing.T) { > >> + > >> `Hello%2c%20%3cb%3eWorld%3c%2fb%3e%20%26amp%3btc%21`, > >> + `%20dir%3d%22ltr%22`, > >> + > >> `c%20%26%26%20alert%28%22Hello%2c%20World%21%22%29%3b`, > >> +- > >> `Hello%2c%20World%20%26%20O%27Reilly%5cx21`, > >> ++ > >> `Hello%2c%20World%20%26%20O%27Reilly%5cu0021`, > >> + // Quotes and parens are escaped but %69 > >> is not over-escaped. HTML escaping is not done. > >> + `greeting=H%69,&addressee=%28World%29`, > >> + > >> `greeting%3dH%2569%2c%26addressee%3d%28World%29%202x%2c%20https%3a%2f%2fgolang.org%2ffavicon.ico%20500.5w`, > >> +diff --git a/src/html/template/escape_test.go > >> b/src/html/template/escape_test.go > >> +index e72a9ba..c709660 100644 > >> +--- a/src/html/template/escape_test.go > >> ++++ b/src/html/template/escape_test.go > >> +@@ -238,7 +238,7 @@ func TestEscape(t *testing.T) { > >> + { > >> + "jsStr", > >> + "<button onclick='alert("{{.H}}")'>", > >> +- `<button > >> onclick='alert("\x3cHello\x3e")'>`, > >> ++ `<button > >> onclick='alert("\u003cHello\u003e")'>`, > >> + }, > >> + { > >> + "badMarshaler", > >> +@@ -259,7 +259,7 @@ func TestEscape(t *testing.T) { > >> + { > >> + "jsRe", > >> + `<button > >> onclick='alert(/{{"foo+bar"}}/.test(""))'>`, > >> +- `<button onclick='alert(/foo\x2bbar/.test(""))'>`, > >> ++ `<button > >> onclick='alert(/foo\u002bbar/.test(""))'>`, > >> + }, > >> + { > >> + "jsReBlank", > >> +@@ -825,7 +825,7 @@ func TestEscapeSet(t *testing.T) { > >> + "main": `<button > >> onclick="title='{{template "helper"}}'; ...">{{template > >> "helper"}}</button>`, > >> + "helper": `{{11}} of {{"<100>"}}`, > >> + }, > >> +- `<button onclick="title='11 of \x3c100\x3e'; > >> ...">11 of <100></button>`, > >> ++ `<button onclick="title='11 of \u003c100\u003e'; > >> ...">11 of <100></button>`, > >> + }, > >> + // A non-recursive template that ends in a different > >> context. > >> + // helper starts in jsCtxRegexp and ends in jsCtxDivOp. > >> +diff --git a/src/html/template/example_test.go > >> b/src/html/template/example_test.go > >> +index 9d965f1..6cf936f 100644 > >> +--- a/src/html/template/example_test.go > >> ++++ b/src/html/template/example_test.go > >> +@@ -116,9 +116,9 @@ func Example_escape() { > >> + // "Fran & Freddie's Diner" > >> <ta...@example.com> > >> + // "Fran & Freddie's Diner" > >> <ta...@example.com> > >> + // "Fran & Freddie's > >> Diner"32<ta...@example.com> > >> +- // \"Fran \x26 Freddie\'s Diner\" \x3cta...@example.com\x3E > >> +- // \"Fran \x26 Freddie\'s Diner\" \x3cta...@example.com\x3E > >> +- // \"Fran \x26 Freddie\'s Diner\"32\x3cta...@example.com\x3E > >> ++ // \"Fran \u0026 Freddie\'s Diner\" \u003cta...@example.com\u003E > >> ++ // \"Fran \u0026 Freddie\'s Diner\" \u003cta...@example.com\u003E > >> ++ // \"Fran \u0026 Freddie\'s Diner\"32\u003cta...@example.com\u003E > >> + // %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E > >> + > >> + } > >> diff --git a/src/html/template/js.go b/src/html/template/js.go > >> index 0e91458..ea9c183 100644 > >> --- a/src/html/template/js.go > >> @@ -173,6 +401,217 @@ index 0e91458..ea9c183 100644 > >> '?': `\?`, > >> '[': `\[`, > >> '\\': `\\`, > >> +diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go > >> +index 075adaa..d7ee47b 100644 > >> +--- a/src/html/template/js_test.go > >> ++++ b/src/html/template/js_test.go > >> +@@ -137,7 +137,7 @@ func TestJSValEscaper(t *testing.T) { > >> + {"foo", `"foo"`}, > >> + // Newlines. > >> + {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`}, > >> +- // "\v" == "v" on IE 6 so use "\x0b" instead. > >> ++ // "\v" == "v" on IE 6 so use "\u000b" instead. > >> + {"\t\x0b", `"\t\u000b"`}, > >> + {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`}, > >> + {[]interface{}{}, "[]"}, > >> +@@ -173,7 +173,7 @@ func TestJSStrEscaper(t *testing.T) { > >> + }{ > >> + {"", ``}, > >> + {"foo", `foo`}, > >> +- {"\u0000", `\0`}, > >> ++ {"\u0000", `\u0000`}, > >> + {"\t", `\t`}, > >> + {"\n", `\n`}, > >> + {"\r", `\r`}, > >> +@@ -183,14 +183,14 @@ func TestJSStrEscaper(t *testing.T) { > >> + {"\\n", `\\n`}, > >> + {"foo\r\nbar", `foo\r\nbar`}, > >> + // Preserve attribute boundaries. > >> +- {`"`, `\x22`}, > >> +- {`'`, `\x27`}, > >> ++ {`"`, `\u0022`}, > >> ++ {`'`, `\u0027`}, > >> + // Allow embedding in HTML without further escaping. > >> +- {`&`, `\x26amp;`}, > >> ++ {`&`, `\u0026amp;`}, > >> + // Prevent breaking out of text node and element > >> boundaries. > >> +- {"</script>", `\x3c\/script\x3e`}, > >> +- {"<![CDATA[", `\x3c![CDATA[`}, > >> +- {"]]>", `]]\x3e`}, > >> ++ {"</script>", `\u003c\/script\u003e`}, > >> ++ {"<![CDATA[", `\u003c![CDATA[`}, > >> ++ {"]]>", `]]\u003e`}, > >> + // > >> https://dev.w3.org/html5/markup/aria/syntax.html#escaping-text-span > >> + // "The text in style, script, title, and textarea > >> elements > >> + // must not have an escaping text span start that is not > >> +@@ -201,11 +201,11 @@ func TestJSStrEscaper(t *testing.T) { > >> + // allow regular text content to be interpreted as script > >> + // allowing script execution via a combination of a JS > >> string > >> + // injection followed by an HTML text injection. > >> +- {"<!--", `\x3c!--`}, > >> +- {"-->", `--\x3e`}, > >> ++ {"<!--", `\u003c!--`}, > >> ++ {"-->", `--\u003e`}, > >> + // From https://code.google.com/p/doctype/wiki/ArticleUtf7 > >> + {"+ADw-script+AD4-alert(1)+ADw-/script+AD4-", > >> +- > >> `\x2bADw-script\x2bAD4-alert(1)\x2bADw-\/script\x2bAD4-`, > >> ++ > >> `\u002bADw-script\u002bAD4-alert(1)\u002bADw-\/script\u002bAD4-`, > >> + }, > >> + // Invalid UTF-8 sequence > >> + {"foo\xA0bar", "foo\xA0bar"}, > >> +@@ -228,7 +228,7 @@ func TestJSRegexpEscaper(t *testing.T) { > >> + }{ > >> + {"", `(?:)`}, > >> + {"foo", `foo`}, > >> +- {"\u0000", `\0`}, > >> ++ {"\u0000", `\u0000`}, > >> + {"\t", `\t`}, > >> + {"\n", `\n`}, > >> + {"\r", `\r`}, > >> +@@ -238,19 +238,19 @@ func TestJSRegexpEscaper(t *testing.T) { > >> + {"\\n", `\\n`}, > >> + {"foo\r\nbar", `foo\r\nbar`}, > >> + // Preserve attribute boundaries. > >> +- {`"`, `\x22`}, > >> +- {`'`, `\x27`}, > >> ++ {`"`, `\u0022`}, > >> ++ {`'`, `\u0027`}, > >> + // Allow embedding in HTML without further escaping. > >> +- {`&`, `\x26amp;`}, > >> ++ {`&`, `\u0026amp;`}, > >> + // Prevent breaking out of text node and element > >> boundaries. > >> +- {"</script>", `\x3c\/script\x3e`}, > >> +- {"<![CDATA[", `\x3c!\[CDATA\[`}, > >> +- {"]]>", `\]\]\x3e`}, > >> ++ {"</script>", `\u003c\/script\u003e`}, > >> ++ {"<![CDATA[", `\u003c!\[CDATA\[`}, > >> ++ {"]]>", `\]\]\u003e`}, > >> + // Escaping text spans. > >> +- {"<!--", `\x3c!\-\-`}, > >> +- {"-->", `\-\-\x3e`}, > >> ++ {"<!--", `\u003c!\-\-`}, > >> ++ {"-->", `\-\-\u003e`}, > >> + {"*", `\*`}, > >> +- {"+", `\x2b`}, > >> ++ {"+", `\u002b`}, > >> + {"?", `\?`}, > >> + {"[](){}", `\[\]\(\)\{\}`}, > >> + {"$foo|x.y", `\$foo\|x\.y`}, > >> +@@ -284,27 +284,27 @@ func TestEscapersOnLower7AndSelectHighCodepoints(t > >> *testing.T) { > >> + { > >> + "jsStrEscaper", > >> + jsStrEscaper, > >> +- "\\0\x01\x02\x03\x04\x05\x06\x07" + > >> +- "\x08\\t\\n\\x0b\\f\\r\x0E\x0F" + > >> +- "\x10\x11\x12\x13\x14\x15\x16\x17" + > >> +- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + > >> +- ` !\x22#$%\x26\x27()*\x2b,-.\/` + > >> +- `0123456789:;\x3c=\x3e?` + > >> ++ `\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007` > >> + > >> ++ `\u0008\t\n\u000b\f\r\u000e\u000f` + > >> ++ > >> `\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017` + > >> ++ > >> `\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f` + > >> ++ ` !\u0022#$%\u0026\u0027()*\u002b,-.\/` + > >> ++ `0123456789:;\u003c=\u003e?` + > >> + `@ABCDEFGHIJKLMNO` + > >> + `PQRSTUVWXYZ[\\]^_` + > >> + "`abcdefghijklmno" + > >> +- "pqrstuvwxyz{|}~\x7f" + > >> ++ "pqrstuvwxyz{|}~\u007f" + > >> + > >> "\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E", > >> + }, > >> + { > >> + "jsRegexpEscaper", > >> + jsRegexpEscaper, > >> +- "\\0\x01\x02\x03\x04\x05\x06\x07" + > >> +- "\x08\\t\\n\\x0b\\f\\r\x0E\x0F" + > >> +- "\x10\x11\x12\x13\x14\x15\x16\x17" + > >> +- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + > >> +- ` !\x22#\$%\x26\x27\(\)\*\x2b,\-\.\/` + > >> +- `0123456789:;\x3c=\x3e\?` + > >> ++ `\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007` > >> + > >> ++ `\u0008\t\n\u000b\f\r\u000e\u000f` + > >> ++ > >> `\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017` + > >> ++ > >> `\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f` + > >> ++ ` > >> !\u0022#\$%\u0026\u0027\(\)\*\u002b,\-\.\/` + > >> ++ `0123456789:;\u003c=\u003e\?` + > >> + `@ABCDEFGHIJKLMNO` + > >> + `PQRSTUVWXYZ\[\\\]\^_` + > >> + "`abcdefghijklmno" + > >> +diff --git a/src/html/template/template_test.go > >> b/src/html/template/template_test.go > >> +index 13e6ba4..86bd4db 100644 > >> +--- a/src/html/template/template_test.go > >> ++++ b/src/html/template/template_test.go > >> +@@ -6,6 +6,7 @@ package template_test > >> + > >> + import ( > >> + "bytes" > >> ++ "encoding/json" > >> + . "html/template" > >> + "strings" > >> + "testing" > >> +@@ -121,6 +122,44 @@ func TestNumbers(t *testing.T) { > >> + c.mustExecute(c.root, nil, "12.34 7.5") > >> + } > >> + > >> ++func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t > >> *testing.T) { > >> ++ // See #33671 and #37634 for more context on this. > >> ++ tests := []struct{ name, in string }{ > >> ++ {"empty", ""}, > >> ++ {"invalid", string(rune(-1))}, > >> ++ {"null", "\u0000"}, > >> ++ {"unit separator", "\u001F"}, > >> ++ {"tab", "\t"}, > >> ++ {"gt and lt", "<>"}, > >> ++ {"quotes", `'"`}, > >> ++ {"ASCII letters", "ASCII letters"}, > >> ++ {"Unicode", "ʕ⊙ϖ⊙ʔ"}, > >> ++ {"Pizza", "🍕"}, > >> ++ } > >> ++ const ( > >> ++ prefix = `<script type="application/ld+json">` > >> ++ suffix = `</script>` > >> ++ templ = prefix + `"{{.}}"` + suffix > >> ++ ) > >> ++ tpl := Must(New("JS string is JSON string").Parse(templ)) > >> ++ for _, tt := range tests { > >> ++ t.Run(tt.name, func(t *testing.T) { > >> ++ var buf bytes.Buffer > >> ++ if err := tpl.Execute(&buf, tt.in); err != nil { > >> ++ t.Fatalf("Cannot render template: %v", err) > >> ++ } > >> ++ trimmed := > >> bytes.TrimSuffix(bytes.TrimPrefix(buf.Bytes(), []byte(prefix)), > >> []byte(suffix)) > >> ++ var got string > >> ++ if err := json.Unmarshal(trimmed, &got); err != > >> nil { > >> ++ t.Fatalf("Cannot parse JS string %q as > >> JSON: %v", trimmed[1:len(trimmed)-1], err) > >> ++ } > >> ++ if got != tt.in { > >> ++ t.Errorf("Serialization changed the string > >> value: got %q want %q", got, tt.in) > >> ++ } > >> ++ }) > >> ++ } > >> ++} > >> ++ > >> + type testCase struct { > >> + t *testing.T > >> + root *Template > >> +diff --git a/src/text/template/exec_test.go > >> b/src/text/template/exec_test.go > >> +index 77294ed..b8a809e 100644 > >> +--- a/src/text/template/exec_test.go > >> ++++ b/src/text/template/exec_test.go > >> +@@ -911,9 +911,9 @@ func TestJSEscaping(t *testing.T) { > >> + {`Go "jump" \`, `Go \"jump\" \\`}, > >> + {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, > >> + {"unprintable \uFDFF", `unprintable \uFDFF`}, > >> +- {`<html>`, `\x3Chtml\x3E`}, > >> +- {`no = in attributes`, `no \x3D in attributes`}, > >> +- {`' does not become HTML entity`, `\x26#x27; does not > >> become HTML entity`}, > >> ++ {`<html>`, `\u003Chtml\u003E`}, > >> ++ {`no = in attributes`, `no \u003D in attributes`}, > >> ++ {`' does not become HTML entity`, `\u0026#x27; does > >> not become HTML entity`}, > >> + } > >> + for _, tc := range testCases { > >> + s := JSEscapeString(tc.in) > >> diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go > >> index 46125bc..f3de9fb 100644 > >> --- 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 @@ > >> +From 7ddce23c7d5b728acf8482f5006497c7b9915f8a Mon Sep 17 00:00:00 2001 > >> +From: Ariel Mashraki <ar...@mashraki.co.il> > >> +Date: Wed, 22 Apr 2020 22:17:56 +0300 > >> +Subject: [PATCH 3/6] text/template: add CommentNode to template parse tree > >> +MIME-Version: 1.0 > >> +Content-Type: text/plain; charset=UTF-8 > >> +Content-Transfer-Encoding: 8bit > >> + > >> +Fixes #34652 > >> + > >> +Change-Id: Icf6e3eda593fed826736f34f95a9d66f5450cc98 > >> +Reviewed-on: https://go-review.googlesource.com/c/go/+/229398 > >> +Reviewed-by: Daniel Martí <mv...@mvdan.cc> > >> +Run-TryBot: Daniel Martí <mv...@mvdan.cc> > >> +TryBot-Result: Gobot Gobot <go...@golang.org> > >> + > >> +Dependency Patch #3 > >> + > >> +Upstream-Status: Backport from > >> https://github.com/golang/go/commit/c8ea03828b0645b1fd5725888e44873b75fcfbb6 > >> +CVE: CVE-2023-24538 > >> +Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> +--- > >> + api/next.txt | 19 +++++++++++++++++++ > >> + src/html/template/escape.go | 2 ++ > >> + src/html/template/template_test.go | 16 ++++++++++++++++ > >> + src/text/template/exec.go | 1 + > >> + src/text/template/parse/lex.go | 8 +++++++- > >> + src/text/template/parse/lex_test.go | 7 +++++-- > >> + src/text/template/parse/node.go | 33 > >> +++++++++++++++++++++++++++++++++ > >> + src/text/template/parse/parse.go | 22 +++++++++++++++++++--- > >> + src/text/template/parse/parse_test.go | 25 +++++++++++++++++++++++++ > >> + 9 files changed, 127 insertions(+), 6 deletions(-) > >> + > >> +diff --git a/api/next.txt b/api/next.txt > >> +index e69de29..076f39e 100644 > >> +--- a/api/next.txt > >> ++++ b/api/next.txt > >> +@@ -0,0 +1,19 @@ > >> ++pkg unicode, const Version = "13.0.0" > >> ++pkg unicode, var Chorasmian *RangeTable > >> ++pkg unicode, var Dives_Akuru *RangeTable > >> ++pkg unicode, var Khitan_Small_Script *RangeTable > >> ++pkg unicode, var Yezidi *RangeTable > >> ++pkg text/template/parse, const NodeComment = 20 > >> ++pkg text/template/parse, const NodeComment NodeType > >> ++pkg text/template/parse, const ParseComments = 1 > >> ++pkg text/template/parse, const ParseComments Mode > >> ++pkg text/template/parse, method (*CommentNode) Copy() Node > >> ++pkg text/template/parse, method (*CommentNode) String() string > >> ++pkg text/template/parse, method (CommentNode) Position() Pos > >> ++pkg text/template/parse, method (CommentNode) Type() NodeType > >> ++pkg text/template/parse, type CommentNode struct > >> ++pkg text/template/parse, type CommentNode struct, Text string > >> ++pkg text/template/parse, type CommentNode struct, embedded NodeType > >> ++pkg text/template/parse, type CommentNode struct, embedded Pos > >> ++pkg text/template/parse, type Mode uint > >> ++pkg text/template/parse, type Tree struct, Mode Mode > >> +diff --git a/src/html/template/escape.go b/src/html/template/escape.go > >> +index f12dafa..8739735 100644 > >> +--- a/src/html/template/escape.go > >> ++++ b/src/html/template/escape.go > >> +@@ -124,6 +124,8 @@ func (e *escaper) escape(c context, n parse.Node) > >> context { > >> + switch n := n.(type) { > >> + case *parse.ActionNode: > >> + return e.escapeAction(c, n) > >> ++ case *parse.CommentNode: > >> ++ return c > >> + case *parse.IfNode: > >> + return e.escapeBranch(c, &n.BranchNode, "if") > >> + case *parse.ListNode: > >> +diff --git a/src/html/template/template_test.go > >> b/src/html/template/template_test.go > >> +index 86bd4db..1f2c888 100644 > >> +--- a/src/html/template/template_test.go > >> ++++ b/src/html/template/template_test.go > >> +@@ -10,6 +10,7 @@ import ( > >> + . "html/template" > >> + "strings" > >> + "testing" > >> ++ "text/template/parse" > >> + ) > >> + > >> + func TestTemplateClone(t *testing.T) { > >> +@@ -160,6 +161,21 @@ func > >> TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) { > >> + } > >> + } > >> + > >> ++func TestSkipEscapeComments(t *testing.T) { > >> ++ c := newTestCase(t) > >> ++ tr := parse.New("root") > >> ++ tr.Mode = parse.ParseComments > >> ++ newT, err := tr.Parse("{{/* A comment */}}{{ 1 }}{{/* Another > >> comment */}}", "", "", make(map[string]*parse.Tree)) > >> ++ if err != nil { > >> ++ t.Fatalf("Cannot parse template text: %v", err) > >> ++ } > >> ++ c.root, err = c.root.AddParseTree("root", newT) > >> ++ if err != nil { > >> ++ t.Fatalf("Cannot add parse tree to template: %v", err) > >> ++ } > >> ++ c.mustExecute(c.root, nil, "1") > >> ++} > >> ++ > >> + type testCase struct { > >> + t *testing.T > >> + root *Template > >> +diff --git a/src/text/template/exec.go b/src/text/template/exec.go > >> +index ac3e741..7ac5175 100644 > >> +--- a/src/text/template/exec.go > >> ++++ b/src/text/template/exec.go > >> +@@ -256,6 +256,7 @@ func (s *state) walk(dot reflect.Value, node > >> parse.Node) { > >> + if len(node.Pipe.Decl) == 0 { > >> + s.printValue(node, val) > >> + } > >> ++ case *parse.CommentNode: > >> + case *parse.IfNode: > >> + s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, > >> node.ElseList) > >> + case *parse.ListNode: > >> +diff --git a/src/text/template/parse/lex.go > >> b/src/text/template/parse/lex.go > >> +index 30371f2..e41373a 100644 > >> +--- a/src/text/template/parse/lex.go > >> ++++ b/src/text/template/parse/lex.go > >> +@@ -41,6 +41,7 @@ const ( > >> + itemBool // boolean constant > >> + itemChar // printable ASCII character; > >> grab bag for comma etc. > >> + itemCharConstant // character constant > >> ++ itemComment // comment text > >> + itemComplex // complex constant (1+2i); > >> imaginary is just a number > >> + itemAssign // equals ('=') introducing an > >> assignment > >> + itemDeclare // colon-equals (':=') > >> introducing a declaration > >> +@@ -112,6 +113,7 @@ type lexer struct { > >> + leftDelim string // start of action > >> + rightDelim string // end of action > >> + trimRightDelim string // end of action with trim marker > >> ++ emitComment bool // emit itemComment tokens. > >> + pos Pos // current position in the input > >> + start Pos // start position of this item > >> + width Pos // width of last rune read from input > >> +@@ -203,7 +205,7 @@ func (l *lexer) drain() { > >> + } > >> + > >> + // lex creates a new scanner for the input string. > >> +-func lex(name, input, left, right string) *lexer { > >> ++func lex(name, input, left, right string, emitComment bool) *lexer { > >> + if left == "" { > >> + left = leftDelim > >> + } > >> +@@ -216,6 +218,7 @@ func lex(name, input, left, right string) *lexer { > >> + leftDelim: left, > >> + rightDelim: right, > >> + trimRightDelim: rightTrimMarker + right, > >> ++ emitComment: emitComment, > >> + items: make(chan item), > >> + line: 1, > >> + startLine: 1, > >> +@@ -323,6 +326,9 @@ func lexComment(l *lexer) stateFn { > >> + if !delim { > >> + return l.errorf("comment ends before closing delimiter") > >> + } > >> ++ if l.emitComment { > >> ++ l.emit(itemComment) > >> ++ } > >> + if trimSpace { > >> + l.pos += trimMarkerLen > >> + } > >> +diff --git a/src/text/template/parse/lex_test.go > >> b/src/text/template/parse/lex_test.go > >> +index 563c4fc..f6d5f28 100644 > >> +--- a/src/text/template/parse/lex_test.go > >> ++++ b/src/text/template/parse/lex_test.go > >> +@@ -15,6 +15,7 @@ var itemName = map[itemType]string{ > >> + itemBool: "bool", > >> + itemChar: "char", > >> + itemCharConstant: "charconst", > >> ++ itemComment: "comment", > >> + itemComplex: "complex", > >> + itemDeclare: ":=", > >> + itemEOF: "EOF", > >> +@@ -90,6 +91,7 @@ var lexTests = []lexTest{ > >> + {"text", `now is the time`, []item{mkItem(itemText, "now is the > >> time"), tEOF}}, > >> + {"text with comment", "hello-{{/* this is a comment */}}-world", > >> []item{ > >> + mkItem(itemText, "hello-"), > >> ++ mkItem(itemComment, "/* this is a comment */"), > >> + mkItem(itemText, "-world"), > >> + tEOF, > >> + }}, > >> +@@ -311,6 +313,7 @@ var lexTests = []lexTest{ > >> + }}, > >> + {"trimming spaces before and after comment", "hello- {{- /* hello > >> */ -}} -world", []item{ > >> + mkItem(itemText, "hello-"), > >> ++ mkItem(itemComment, "/* hello */"), > >> + mkItem(itemText, "-world"), > >> + tEOF, > >> + }}, > >> +@@ -389,7 +392,7 @@ var lexTests = []lexTest{ > >> + > >> + // collect gathers the emitted items into a slice. > >> + func collect(t *lexTest, left, right string) (items []item) { > >> +- l := lex(t.name, t.input, left, right) > >> ++ l := lex(t.name, t.input, left, right, true) > >> + for { > >> + item := l.nextItem() > >> + items = append(items, item) > >> +@@ -529,7 +532,7 @@ func TestPos(t *testing.T) { > >> + func TestShutdown(t *testing.T) { > >> + // We need to duplicate template.Parse here to hold on to the > >> lexer. > >> + const text = "erroneous{{define}}{{else}}1234" > >> +- lexer := lex("foo", text, "{{", "}}") > >> ++ lexer := lex("foo", text, "{{", "}}", false) > >> + _, err := New("root").parseLexer(lexer) > >> + if err == nil { > >> + t.Fatalf("expected error") > >> +diff --git a/src/text/template/parse/node.go > >> b/src/text/template/parse/node.go > >> +index 1c116ea..a9dad5e 100644 > >> +--- a/src/text/template/parse/node.go > >> ++++ b/src/text/template/parse/node.go > >> +@@ -70,6 +70,7 @@ const ( > >> + NodeTemplate // A template invocation action. > >> + NodeVariable // A $ variable. > >> + NodeWith // A with action. > >> ++ NodeComment // A comment. > >> + ) > >> + > >> + // Nodes. > >> +@@ -149,6 +150,38 @@ func (t *TextNode) Copy() Node { > >> + return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: > >> append([]byte{}, t.Text...)} > >> + } > >> + > >> ++// CommentNode holds a comment. > >> ++type CommentNode struct { > >> ++ NodeType > >> ++ Pos > >> ++ tr *Tree > >> ++ Text string // Comment text. > >> ++} > >> ++ > >> ++func (t *Tree) newComment(pos Pos, text string) *CommentNode { > >> ++ return &CommentNode{tr: t, NodeType: NodeComment, Pos: pos, Text: > >> text} > >> ++} > >> ++ > >> ++func (c *CommentNode) String() string { > >> ++ var sb strings.Builder > >> ++ c.writeTo(&sb) > >> ++ return sb.String() > >> ++} > >> ++ > >> ++func (c *CommentNode) writeTo(sb *strings.Builder) { > >> ++ sb.WriteString("{{") > >> ++ sb.WriteString(c.Text) > >> ++ sb.WriteString("}}") > >> ++} > >> ++ > >> ++func (c *CommentNode) tree() *Tree { > >> ++ return c.tr > >> ++} > >> ++ > >> ++func (c *CommentNode) Copy() Node { > >> ++ return &CommentNode{tr: c.tr, NodeType: NodeComment, Pos: c.Pos, > >> Text: c.Text} > >> ++} > >> ++ > >> + // PipeNode holds a pipeline with optional declaration > >> + type PipeNode struct { > >> + NodeType > >> +diff --git a/src/text/template/parse/parse.go > >> b/src/text/template/parse/parse.go > >> +index c9b80f4..496d8bf 100644 > >> +--- a/src/text/template/parse/parse.go > >> ++++ b/src/text/template/parse/parse.go > >> +@@ -21,6 +21,7 @@ type Tree struct { > >> + Name string // name of the template represented by the > >> tree. > >> + ParseName string // name of the top-level template during > >> parsing, for error messages. > >> + Root *ListNode // top-level root of the tree. > >> ++ Mode Mode // parsing mode. > >> + text string // text parsed to create the template (or its > >> parent) > >> + // Parsing only; cleared after parse. > >> + funcs []map[string]interface{} > >> +@@ -29,8 +30,16 @@ type Tree struct { > >> + peekCount int > >> + vars []string // variables defined at the moment. > >> + treeSet map[string]*Tree > >> ++ mode Mode > >> + } > >> + > >> ++// A mode value is a set of flags (or 0). Modes control parser behavior. > >> ++type Mode uint > >> ++ > >> ++const ( > >> ++ ParseComments Mode = 1 << iota // parse comments and add them to > >> AST > >> ++) > >> ++ > >> + // Copy returns a copy of the Tree. Any parsing state is discarded. > >> + func (t *Tree) Copy() *Tree { > >> + if t == nil { > >> +@@ -220,7 +229,8 @@ func (t *Tree) stopParse() { > >> + func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet > >> map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) > >> { > >> + defer t.recover(&err) > >> + t.ParseName = t.Name > >> +- t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim), > >> treeSet) > >> ++ emitComment := t.Mode&ParseComments != 0 > >> ++ t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim, > >> emitComment), treeSet) > >> + t.text = text > >> + t.parse() > >> + t.add() > >> +@@ -240,12 +250,14 @@ func (t *Tree) add() { > >> + } > >> + } > >> + > >> +-// IsEmptyTree reports whether this tree (node) is empty of everything > >> but space. > >> ++// IsEmptyTree reports whether this tree (node) is empty of everything > >> but space or comments. > >> + func IsEmptyTree(n Node) bool { > >> + switch n := n.(type) { > >> + case nil: > >> + return true > >> + case *ActionNode: > >> ++ case *CommentNode: > >> ++ return true > >> + case *IfNode: > >> + case *ListNode: > >> + for _, node := range n.Nodes { > >> +@@ -276,6 +288,7 @@ func (t *Tree) parse() { > >> + if t.nextNonSpace().typ == itemDefine { > >> + newT := New("definition") // name will be > >> updated once we know it. > >> + newT.text = t.text > >> ++ newT.Mode = t.Mode > >> + newT.ParseName = t.ParseName > >> + newT.startParse(t.funcs, t.lex, t.treeSet) > >> + newT.parseDefinition() > >> +@@ -331,13 +344,15 @@ func (t *Tree) itemList() (list *ListNode, next > >> Node) { > >> + } > >> + > >> + // textOrAction: > >> +-// text | action > >> ++// text | comment | action > >> + func (t *Tree) textOrAction() Node { > >> + switch token := t.nextNonSpace(); token.typ { > >> + case itemText: > >> + return t.newText(token.pos, token.val) > >> + case itemLeftDelim: > >> + return t.action() > >> ++ case itemComment: > >> ++ return t.newComment(token.pos, token.val) > >> + default: > >> + t.unexpected(token, "input") > >> + } > >> +@@ -539,6 +554,7 @@ func (t *Tree) blockControl() Node { > >> + > >> + block := New(name) // name will be updated once we know it. > >> + block.text = t.text > >> ++ block.Mode = t.Mode > >> + block.ParseName = t.ParseName > >> + block.startParse(t.funcs, t.lex, t.treeSet) > >> + var end Node > >> +diff --git a/src/text/template/parse/parse_test.go > >> b/src/text/template/parse/parse_test.go > >> +index 4e09a78..d9c13c5 100644 > >> +--- a/src/text/template/parse/parse_test.go > >> ++++ b/src/text/template/parse/parse_test.go > >> +@@ -348,6 +348,30 @@ func TestParseCopy(t *testing.T) { > >> + testParse(true, t) > >> + } > >> + > >> ++func TestParseWithComments(t *testing.T) { > >> ++ textFormat = "%q" > >> ++ defer func() { textFormat = "%s" }() > >> ++ tests := [...]parseTest{ > >> ++ {"comment", "{{/*\n\n\n*/}}", noError, "{{/*\n\n\n*/}}"}, > >> ++ {"comment trim left", "x \r\n\t{{- /* hi */}}", noError, > >> `"x"{{/* hi */}}`}, > >> ++ {"comment trim right", "{{/* hi */ -}}\n\n\ty", noError, > >> `{{/* hi */}}"y"`}, > >> ++ {"comment trim left and right", "x \r\n\t{{- /* */ > >> -}}\n\n\ty", noError, `"x"{{/* */}}"y"`}, > >> ++ } > >> ++ for _, test := range tests { > >> ++ t.Run(test.name, func(t *testing.T) { > >> ++ tr := New(test.name) > >> ++ tr.Mode = ParseComments > >> ++ tmpl, err := tr.Parse(test.input, "", "", > >> make(map[string]*Tree)) > >> ++ if err != nil { > >> ++ t.Errorf("%q: expected error; got none", > >> test.name) > >> ++ } > >> ++ if result := tmpl.Root.String(); result != > >> test.result { > >> ++ t.Errorf("%s=(%q): > >> got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result) > >> ++ } > >> ++ }) > >> ++ } > >> ++} > >> ++ > >> + type isEmptyTest struct { > >> + name string > >> + input string > >> +@@ -358,6 +382,7 @@ var isEmptyTests = []isEmptyTest{ > >> + {"empty", ``, true}, > >> + {"nonempty", `hello`, false}, > >> + {"spaces only", " \t\n \t\n", true}, > >> ++ {"comment only", "{{/* comment */}}", true}, > >> + {"definition", `{{define "x"}}something{{end}}`, true}, > >> + {"definitions and space", "{{define > >> `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true}, > >> + {"definitions and text", "{{define > >> `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n", false}, > >> +-- > >> +2.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 @@ > >> +From 760d88497091fb5d6d231a18e6f4e06ecb9af9b2 Mon Sep 17 00:00:00 2001 > >> +From: Russ Cox <r...@golang.org> > >> +Date: Thu, 10 Sep 2020 18:53:26 -0400 > >> +Subject: [PATCH 4/6] text/template: allow newlines inside action > >> delimiters > >> + > >> +This allows multiline constructs like: > >> + > >> + {{"hello" | > >> + printf}} > >> + > >> +Now that unclosed actions can span multiple lines, > >> +track and report the start of the action when reporting errors. > >> + > >> +Also clean up a few "unexpected <error message>" to be just "<error > >> message>". > >> + > >> +Fixes #29770. > >> + > >> +Change-Id: I54c6c016029a8328b7902a4b6d85eab713ec3285 > >> +Reviewed-on: https://go-review.googlesource.com/c/go/+/254257 > >> +Trust: Russ Cox <r...@golang.org> > >> +Run-TryBot: Russ Cox <r...@golang.org> > >> +TryBot-Result: Go Bot <go...@golang.org> > >> +Reviewed-by: Rob Pike <r...@golang.org> > >> + > >> +Dependency Patch #4 > >> + > >> +Upstream-Status: Backport from > >> https://github.com/golang/go/commit/9384d34c58099657bb1b133beaf3ff37ada9b017 > >> +CVE: CVE-2023-24538 > >> +Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> +--- > >> + src/text/template/doc.go | 21 ++++----- > >> + src/text/template/exec_test.go | 2 +- > >> + src/text/template/parse/lex.go | 84 > >> +++++++++++++++++------------------ > >> + src/text/template/parse/lex_test.go | 2 +- > >> + src/text/template/parse/parse.go | 59 +++++++++++++----------- > >> + src/text/template/parse/parse_test.go | 36 ++++++++++++--- > >> + 6 files changed, 117 insertions(+), 87 deletions(-) > >> + > >> +diff --git a/src/text/template/doc.go b/src/text/template/doc.go > >> +index 4b0efd2..7b30294 100644 > >> +--- a/src/text/template/doc.go > >> ++++ b/src/text/template/doc.go > >> +@@ -40,16 +40,17 @@ More intricate examples appear below. > >> + Text and spaces > >> + > >> + By default, all text between actions is copied verbatim when the > >> template is > >> +-executed. For example, the string " items are made of " in the example > >> above appears > >> +-on standard output when the program is run. > >> +- > >> +-However, to aid in formatting template source code, if an action's left > >> delimiter > >> +-(by default "{{") is followed immediately by a minus sign and ASCII > >> space character > >> +-("{{- "), all trailing white space is trimmed from the immediately > >> preceding text. > >> +-Similarly, if the right delimiter ("}}") is preceded by a space and > >> minus sign > >> +-(" -}}"), all leading white space is trimmed from the immediately > >> following text. > >> +-In these trim markers, the ASCII space must be present; "{{-3}}" parses > >> as an > >> +-action containing the number -3. > >> ++executed. For example, the string " items are made of " in the example > >> above > >> ++appears on standard output when the program is run. > >> ++ > >> ++However, to aid in formatting template source code, if an action's left > >> ++delimiter (by default "{{") is followed immediately by a minus sign and > >> white > >> ++space, all trailing white space is trimmed from the immediately > >> preceding text. > >> ++Similarly, if the right delimiter ("}}") is preceded by white space and > >> a minus > >> ++sign, all leading white space is trimmed from the immediately following > >> text. > >> ++In these trim markers, the white space must be present: > >> ++"{{- 3}}" is like "{{3}}" but trims the immediately preceding text, while > >> ++"{{-3}}" parses as an action containing the number -3. > >> + > >> + For instance, when executing the template whose source is > >> + > >> +diff --git a/src/text/template/exec_test.go > >> b/src/text/template/exec_test.go > >> +index b8a809e..3309b33 100644 > >> +--- a/src/text/template/exec_test.go > >> ++++ b/src/text/template/exec_test.go > >> +@@ -1295,7 +1295,7 @@ func TestUnterminatedStringError(t *testing.T) { > >> + t.Fatal("expected error") > >> + } > >> + str := err.Error() > >> +- if !strings.Contains(str, "X:3: unexpected unterminated raw quoted > >> string") { > >> ++ if !strings.Contains(str, "X:3: unterminated raw quoted string") { > >> + t.Fatalf("unexpected error: %s", str) > >> + } > >> + } > >> +diff --git a/src/text/template/parse/lex.go > >> b/src/text/template/parse/lex.go > >> +index e41373a..6784071 100644 > >> +--- a/src/text/template/parse/lex.go > >> ++++ b/src/text/template/parse/lex.go > >> +@@ -92,15 +92,14 @@ const eof = -1 > >> + // If the action begins "{{- " rather than "{{", then all > >> space/tab/newlines > >> + // preceding the action are trimmed; conversely if it ends " -}}" the > >> + // leading spaces are trimmed. This is done entirely in the lexer; the > >> +-// parser never sees it happen. We require an ASCII space to be > >> +-// present to avoid ambiguity with things like "{{-3}}". It reads > >> ++// parser never sees it happen. We require an ASCII space (' ', \t, \r, > >> \n) > >> ++// to be present to avoid ambiguity with things like "{{-3}}". It reads > >> + // better with the space present anyway. For simplicity, only ASCII > >> +-// space does the job. > >> ++// does the job. > >> + const ( > >> +- spaceChars = " \t\r\n" // These are the space characters > >> defined by Go itself. > >> +- leftTrimMarker = "- " // Attached to left delimiter, trims > >> trailing spaces from preceding text. > >> +- rightTrimMarker = " -" // Attached to right delimiter, trims > >> leading spaces from following text. > >> +- trimMarkerLen = Pos(len(leftTrimMarker)) > >> ++ spaceChars = " \t\r\n" // These are the space characters > >> defined by Go itself. > >> ++ trimMarker = '-' // Attached to left/right delimiter, > >> trims trailing spaces from preceding/following text. > >> ++ trimMarkerLen = Pos(1 + 1) // marker plus space before or after > >> + ) > >> + > >> + // stateFn represents the state of the scanner as a function that > >> returns the next state. > >> +@@ -108,19 +107,18 @@ type stateFn func(*lexer) stateFn > >> + > >> + // lexer holds the state of the scanner. > >> + type lexer struct { > >> +- name string // the name of the input; used only for > >> error reports > >> +- input string // the string being scanned > >> +- leftDelim string // start of action > >> +- rightDelim string // end of action > >> +- trimRightDelim string // end of action with trim marker > >> +- emitComment bool // emit itemComment tokens. > >> +- pos Pos // current position in the input > >> +- start Pos // start position of this item > >> +- width Pos // width of last rune read from input > >> +- items chan item // channel of scanned items > >> +- parenDepth int // nesting depth of ( ) exprs > >> +- line int // 1+number of newlines seen > >> +- startLine int // start line of this item > >> ++ name string // the name of the input; used only for > >> error reports > >> ++ input string // the string being scanned > >> ++ leftDelim string // start of action > >> ++ rightDelim string // end of action > >> ++ emitComment bool // emit itemComment tokens. > >> ++ pos Pos // current position in the input > >> ++ start Pos // start position of this item > >> ++ width Pos // width of last rune read from input > >> ++ items chan item // channel of scanned items > >> ++ parenDepth int // nesting depth of ( ) exprs > >> ++ line int // 1+number of newlines seen > >> ++ startLine int // start line of this item > >> + } > >> + > >> + // next returns the next rune in the input. > >> +@@ -213,15 +211,14 @@ func lex(name, input, left, right string, > >> emitComment bool) *lexer { > >> + right = rightDelim > >> + } > >> + l := &lexer{ > >> +- name: name, > >> +- input: input, > >> +- leftDelim: left, > >> +- rightDelim: right, > >> +- trimRightDelim: rightTrimMarker + right, > >> +- emitComment: emitComment, > >> +- items: make(chan item), > >> +- line: 1, > >> +- startLine: 1, > >> ++ name: name, > >> ++ input: input, > >> ++ leftDelim: left, > >> ++ rightDelim: right, > >> ++ emitComment: emitComment, > >> ++ items: make(chan item), > >> ++ line: 1, > >> ++ startLine: 1, > >> + } > >> + go l.run() > >> + return l > >> +@@ -251,7 +248,7 @@ func lexText(l *lexer) stateFn { > >> + ldn := Pos(len(l.leftDelim)) > >> + l.pos += Pos(x) > >> + trimLength := Pos(0) > >> +- if strings.HasPrefix(l.input[l.pos+ldn:], leftTrimMarker) { > >> ++ if hasLeftTrimMarker(l.input[l.pos+ldn:]) { > >> + trimLength = > >> rightTrimLength(l.input[l.start:l.pos]) > >> + } > >> + l.pos -= trimLength > >> +@@ -280,7 +277,7 @@ func rightTrimLength(s string) Pos { > >> + > >> + // atRightDelim reports whether the lexer is at a right delimiter, > >> possibly preceded by a trim marker. > >> + func (l *lexer) atRightDelim() (delim, trimSpaces bool) { > >> +- if strings.HasPrefix(l.input[l.pos:], l.trimRightDelim) { // With > >> trim marker. > >> ++ if hasRightTrimMarker(l.input[l.pos:]) && > >> strings.HasPrefix(l.input[l.pos+trimMarkerLen:], l.rightDelim) { // With > >> trim marker. > >> + return true, true > >> + } > >> + if strings.HasPrefix(l.input[l.pos:], l.rightDelim) { // Without > >> trim marker. > >> +@@ -297,7 +294,7 @@ func leftTrimLength(s string) Pos { > >> + // lexLeftDelim scans the left delimiter, which is known to be present, > >> possibly with a trim marker. > >> + func lexLeftDelim(l *lexer) stateFn { > >> + l.pos += Pos(len(l.leftDelim)) > >> +- trimSpace := strings.HasPrefix(l.input[l.pos:], leftTrimMarker) > >> ++ trimSpace := hasLeftTrimMarker(l.input[l.pos:]) > >> + afterMarker := Pos(0) > >> + if trimSpace { > >> + afterMarker = trimMarkerLen > >> +@@ -342,7 +339,7 @@ func lexComment(l *lexer) stateFn { > >> + > >> + // lexRightDelim scans the right delimiter, which is known to be > >> present, possibly with a trim marker. > >> + func lexRightDelim(l *lexer) stateFn { > >> +- trimSpace := strings.HasPrefix(l.input[l.pos:], rightTrimMarker) > >> ++ trimSpace := hasRightTrimMarker(l.input[l.pos:]) > >> + if trimSpace { > >> + l.pos += trimMarkerLen > >> + l.ignore() > >> +@@ -369,7 +366,7 @@ func lexInsideAction(l *lexer) stateFn { > >> + return l.errorf("unclosed left paren") > >> + } > >> + switch r := l.next(); { > >> +- case r == eof || isEndOfLine(r): > >> ++ case r == eof: > >> + return l.errorf("unclosed action") > >> + case isSpace(r): > >> + l.backup() // Put space back in case we have " -}}". > >> +@@ -439,7 +436,7 @@ func lexSpace(l *lexer) stateFn { > >> + } > >> + // Be careful about a trim-marked closing delimiter, which has a > >> minus > >> + // after a space. We know there is a space, so check for the '-' > >> that might follow. > >> +- if strings.HasPrefix(l.input[l.pos-1:], l.trimRightDelim) { > >> ++ if hasRightTrimMarker(l.input[l.pos-1:]) && > >> strings.HasPrefix(l.input[l.pos-1+trimMarkerLen:], l.rightDelim) { > >> + l.backup() // Before the space. > >> + if numSpaces == 1 { > >> + return lexRightDelim // On the delim, so go right > >> to that. > >> +@@ -526,7 +523,7 @@ func lexFieldOrVariable(l *lexer, typ itemType) > >> stateFn { > >> + // day to implement arithmetic. > >> + func (l *lexer) atTerminator() bool { > >> + r := l.peek() > >> +- if isSpace(r) || isEndOfLine(r) { > >> ++ if isSpace(r) { > >> + return true > >> + } > >> + switch r { > >> +@@ -657,15 +654,18 @@ Loop: > >> + > >> + // isSpace reports whether r is a space character. > >> + func isSpace(r rune) bool { > >> +- return r == ' ' || r == '\t' > >> +-} > >> +- > >> +-// isEndOfLine reports whether r is an end-of-line character. > >> +-func isEndOfLine(r rune) bool { > >> +- return r == '\r' || r == '\n' > >> ++ return r == ' ' || r == '\t' || r == '\r' || r == '\n' > >> + } > >> + > >> + // isAlphaNumeric reports whether r is an alphabetic, digit, or > >> underscore. > >> + func isAlphaNumeric(r rune) bool { > >> + return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) > >> + } > >> ++ > >> ++func hasLeftTrimMarker(s string) bool { > >> ++ return len(s) >= 2 && s[0] == trimMarker && isSpace(rune(s[1])) > >> ++} > >> ++ > >> ++func hasRightTrimMarker(s string) bool { > >> ++ return len(s) >= 2 && isSpace(rune(s[0])) && s[1] == trimMarker > >> ++} > >> +diff --git a/src/text/template/parse/lex_test.go > >> b/src/text/template/parse/lex_test.go > >> +index f6d5f28..6510eed 100644 > >> +--- a/src/text/template/parse/lex_test.go > >> ++++ b/src/text/template/parse/lex_test.go > >> +@@ -323,7 +323,7 @@ var lexTests = []lexTest{ > >> + tLeft, > >> + mkItem(itemError, "unrecognized character in action: > >> U+0001"), > >> + }}, > >> +- {"unclosed action", "{{\n}}", []item{ > >> ++ {"unclosed action", "{{", []item{ > >> + tLeft, > >> + mkItem(itemError, "unclosed action"), > >> + }}, > >> +diff --git a/src/text/template/parse/parse.go > >> b/src/text/template/parse/parse.go > >> +index 496d8bf..5e6e512 100644 > >> +--- a/src/text/template/parse/parse.go > >> ++++ b/src/text/template/parse/parse.go > >> +@@ -24,13 +24,14 @@ type Tree struct { > >> + Mode Mode // parsing mode. > >> + text string // text parsed to create the template (or its > >> parent) > >> + // Parsing only; cleared after parse. > >> +- funcs []map[string]interface{} > >> +- lex *lexer > >> +- token [3]item // three-token lookahead for parser. > >> +- peekCount int > >> +- vars []string // variables defined at the moment. > >> +- treeSet map[string]*Tree > >> +- mode Mode > >> ++ funcs []map[string]interface{} > >> ++ lex *lexer > >> ++ token [3]item // three-token lookahead for parser. > >> ++ peekCount int > >> ++ vars []string // variables defined at the moment. > >> ++ treeSet map[string]*Tree > >> ++ actionLine int // line of left delim starting action > >> ++ mode Mode > >> + } > >> + > >> + // A mode value is a set of flags (or 0). Modes control parser behavior. > >> +@@ -187,6 +188,16 @@ func (t *Tree) expectOneOf(expected1, expected2 > >> itemType, context string) item { > >> + > >> + // unexpected complains about the token and terminates processing. > >> + func (t *Tree) unexpected(token item, context string) { > >> ++ if token.typ == itemError { > >> ++ extra := "" > >> ++ if t.actionLine != 0 && t.actionLine != token.line { > >> ++ extra = fmt.Sprintf(" in action started at %s:%d", > >> t.ParseName, t.actionLine) > >> ++ if strings.HasSuffix(token.val, " action") { > >> ++ extra = extra[len(" in action"):] // avoid > >> "action in action" > >> ++ } > >> ++ } > >> ++ t.errorf("%s%s", token, extra) > >> ++ } > >> + t.errorf("unexpected %s in %s", token, context) > >> + } > >> + > >> +@@ -350,6 +361,8 @@ func (t *Tree) textOrAction() Node { > >> + case itemText: > >> + return t.newText(token.pos, token.val) > >> + case itemLeftDelim: > >> ++ t.actionLine = token.line > >> ++ defer t.clearActionLine() > >> + return t.action() > >> + case itemComment: > >> + return t.newComment(token.pos, token.val) > >> +@@ -359,6 +372,10 @@ func (t *Tree) textOrAction() Node { > >> + return nil > >> + } > >> + > >> ++func (t *Tree) clearActionLine() { > >> ++ t.actionLine = 0 > >> ++} > >> ++ > >> + // Action: > >> + // control > >> + // command ("|" command)* > >> +@@ -384,12 +401,12 @@ func (t *Tree) action() (n Node) { > >> + t.backup() > >> + token := t.peek() > >> + // Do not pop variables; they persist until "end". > >> +- return t.newAction(token.pos, token.line, t.pipeline("command")) > >> ++ return t.newAction(token.pos, token.line, t.pipeline("command", > >> itemRightDelim)) > >> + } > >> + > >> + // Pipeline: > >> + // declarations? command ('|' command)* > >> +-func (t *Tree) pipeline(context string) (pipe *PipeNode) { > >> ++func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) { > >> + token := t.peekNonSpace() > >> + pipe = t.newPipeline(token.pos, token.line, nil) > >> + // Are there declarations or assignments? > >> +@@ -430,12 +447,9 @@ decls: > >> + } > >> + for { > >> + switch token := t.nextNonSpace(); token.typ { > >> +- case itemRightDelim, itemRightParen: > >> ++ case end: > >> + // At this point, the pipeline is complete > >> + t.checkPipeline(pipe, context) > >> +- if token.typ == itemRightParen { > >> +- t.backup() > >> +- } > >> + return > >> + case itemBool, itemCharConstant, itemComplex, itemDot, > >> itemField, itemIdentifier, > >> + itemNumber, itemNil, itemRawString, itemString, > >> itemVariable, itemLeftParen: > >> +@@ -464,7 +478,7 @@ func (t *Tree) checkPipeline(pipe *PipeNode, context > >> string) { > >> + > >> + func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, > >> line int, pipe *PipeNode, list, elseList *ListNode) { > >> + defer t.popVars(len(t.vars)) > >> +- pipe = t.pipeline(context) > >> ++ pipe = t.pipeline(context, itemRightDelim) > >> + var next Node > >> + list, next = t.itemList() > >> + switch next.Type() { > >> +@@ -550,7 +564,7 @@ func (t *Tree) blockControl() Node { > >> + > >> + token := t.nextNonSpace() > >> + name := t.parseTemplateName(token, context) > >> +- pipe := t.pipeline(context) > >> ++ pipe := t.pipeline(context, itemRightDelim) > >> + > >> + block := New(name) // name will be updated once we know it. > >> + block.text = t.text > >> +@@ -580,7 +594,7 @@ func (t *Tree) templateControl() Node { > >> + if t.nextNonSpace().typ != itemRightDelim { > >> + t.backup() > >> + // Do not pop variables; they persist until "end". > >> +- pipe = t.pipeline(context) > >> ++ pipe = t.pipeline(context, itemRightDelim) > >> + } > >> + return t.newTemplate(token.pos, token.line, name, pipe) > >> + } > >> +@@ -614,13 +628,12 @@ func (t *Tree) command() *CommandNode { > >> + switch token := t.next(); token.typ { > >> + case itemSpace: > >> + continue > >> +- case itemError: > >> +- t.errorf("%s", token.val) > >> + case itemRightDelim, itemRightParen: > >> + t.backup() > >> + case itemPipe: > >> ++ // nothing here; break loop below > >> + default: > >> +- t.errorf("unexpected %s in operand", token) > >> ++ t.unexpected(token, "operand") > >> + } > >> + break > >> + } > >> +@@ -675,8 +688,6 @@ func (t *Tree) operand() Node { > >> + // A nil return means the next item is not a term. > >> + func (t *Tree) term() Node { > >> + switch token := t.nextNonSpace(); token.typ { > >> +- case itemError: > >> +- t.errorf("%s", token.val) > >> + case itemIdentifier: > >> + if !t.hasFunction(token.val) { > >> + t.errorf("function %q not defined", token.val) > >> +@@ -699,11 +710,7 @@ func (t *Tree) term() Node { > >> + } > >> + return number > >> + case itemLeftParen: > >> +- pipe := t.pipeline("parenthesized pipeline") > >> +- if token := t.next(); token.typ != itemRightParen { > >> +- t.errorf("unclosed right paren: unexpected %s", > >> token) > >> +- } > >> +- return pipe > >> ++ return t.pipeline("parenthesized pipeline", itemRightParen) > >> + case itemString, itemRawString: > >> + s, err := strconv.Unquote(token.val) > >> + if err != nil { > >> +diff --git a/src/text/template/parse/parse_test.go > >> b/src/text/template/parse/parse_test.go > >> +index d9c13c5..220f984 100644 > >> +--- a/src/text/template/parse/parse_test.go > >> ++++ b/src/text/template/parse/parse_test.go > >> +@@ -250,6 +250,13 @@ var parseTests = []parseTest{ > >> + {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", > >> noError, `"x""y"`}, > >> + {"block definition", `{{block "foo" .}}hello{{end}}`, noError, > >> + `{{template "foo" .}}`}, > >> ++ > >> ++ {"newline in assignment", "{{ $x \n := \n 1 \n }}", noError, "{{$x > >> := 1}}"}, > >> ++ {"newline in empty action", "{{\n}}", hasError, "{{\n}}"}, > >> ++ {"newline in pipeline", "{{\n\"x\"\n|\nprintf\n}}", noError, > >> `{{"x" | printf}}`}, > >> ++ {"newline in comment", "{{/*\nhello\n*/}}", noError, ""}, > >> ++ {"newline in comment", "{{-\n/*\nhello\n*/\n-}}", noError, ""}, > >> ++ > >> + // Errors. > >> + {"unclosed action", "hello{{range", hasError, ""}, > >> + {"unmatched end", "{{end}}", hasError, ""}, > >> +@@ -426,23 +433,38 @@ var errorTests = []parseTest{ > >> + // Check line numbers are accurate. > >> + {"unclosed1", > >> + "line1\n{{", > >> +- hasError, `unclosed1:2: unexpected unclosed action in > >> command`}, > >> ++ hasError, `unclosed1:2: unclosed action`}, > >> + {"unclosed2", > >> + "line1\n{{define `x`}}line2\n{{", > >> +- hasError, `unclosed2:3: unexpected unclosed action in > >> command`}, > >> ++ hasError, `unclosed2:3: unclosed action`}, > >> ++ {"unclosed3", > >> ++ "line1\n{{\"x\"\n\"y\"\n", > >> ++ hasError, `unclosed3:4: unclosed action started at > >> unclosed3:2`}, > >> ++ {"unclosed4", > >> ++ "{{\n\n\n\n\n", > >> ++ hasError, `unclosed4:6: unclosed action started at > >> unclosed4:1`}, > >> ++ {"var1", > >> ++ "line1\n{{\nx\n}}", > >> ++ hasError, `var1:3: function "x" not defined`}, > >> + // Specific errors. > >> + {"function", > >> + "{{foo}}", > >> + hasError, `function "foo" not defined`}, > >> +- {"comment", > >> ++ {"comment1", > >> + "{{/*}}", > >> +- hasError, `unclosed comment`}, > >> ++ hasError, `comment1:1: unclosed comment`}, > >> ++ {"comment2", > >> ++ "{{/*\nhello\n}}", > >> ++ hasError, `comment2:1: unclosed comment`}, > >> + {"lparen", > >> + "{{.X (1 2 3}}", > >> + hasError, `unclosed left paren`}, > >> + {"rparen", > >> +- "{{.X 1 2 3)}}", > >> +- hasError, `unexpected ")"`}, > >> ++ "{{.X 1 2 3 ) }}", > >> ++ hasError, `unexpected ")" in command`}, > >> ++ {"rparen2", > >> ++ "{{(.X 1 2 3", > >> ++ hasError, `unclosed action`}, > >> + {"space", > >> + "{{`x`3}}", > >> + hasError, `in operand`}, > >> +@@ -488,7 +510,7 @@ var errorTests = []parseTest{ > >> + hasError, `missing value for parenthesized pipeline`}, > >> + {"multilinerawstring", > >> + "{{ $v := `\n` }} {{", > >> +- hasError, `multilinerawstring:2: unexpected unclosed > >> action`}, > >> ++ hasError, `multilinerawstring:2: unclosed action`}, > >> + {"rangeundefvar", > >> + "{{range $k}}{{end}}", > >> + hasError, `undefined variable`}, > >> +-- > >> +2.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 @@ > >> +From e0e6bca6ddc0e6d9fa3a5b644af9b446924fbf83 Mon Sep 17 00:00:00 2001 > >> +From: Russ Cox <r...@golang.org> > >> +Date: Thu, 20 May 2021 12:46:33 -0400 > >> +Subject: [PATCH 5/6] html/template, text/template: implement break and > >> + continue for range loops > >> + > >> +Break and continue for range loops was accepted as a proposal in June > >> 2017. > >> +It was implemented in CL 66410 (Oct 2017) > >> +but then rolled back in CL 92155 (Feb 2018) > >> +because html/template changes had not been implemented. > >> + > >> +This CL reimplements break and continue in text/template > >> +and then adds support for them in html/template as well. > >> + > >> +Fixes #20531. > >> + > >> +Change-Id: I05330482a976f1c078b4b49c2287bd9031bb7616 > >> +Reviewed-on: https://go-review.googlesource.com/c/go/+/321491 > >> +Trust: Russ Cox <r...@golang.org> > >> +Run-TryBot: Russ Cox <r...@golang.org> > >> +TryBot-Result: Go Bot <go...@golang.org> > >> +Reviewed-by: Rob Pike <r...@golang.org> > >> + > >> +Dependency Patch #5 > >> + > >> +Upstream-Status: Backport from > >> https://github.com/golang/go/commit/d0dd26a88c019d54f22463daae81e785f5867565 > >> +CVE: CVE-2023-24538 > >> +Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> +--- > >> + src/html/template/context.go | 4 ++ > >> + src/html/template/escape.go | 71 > >> ++++++++++++++++++++++++++++++++++- > >> + src/html/template/escape_test.go | 24 ++++++++++++ > >> + src/text/template/doc.go | 8 ++++ > >> + src/text/template/exec.go | 24 +++++++++++- > >> + src/text/template/exec_test.go | 2 + > >> + src/text/template/parse/lex.go | 13 ++++++- > >> + src/text/template/parse/lex_test.go | 2 + > >> + src/text/template/parse/node.go | 36 ++++++++++++++++++ > >> + src/text/template/parse/parse.go | 42 ++++++++++++++++++++- > >> + src/text/template/parse/parse_test.go | 8 ++++ > >> + 11 files changed, 230 insertions(+), 4 deletions(-) > >> + > >> +diff --git a/src/html/template/context.go b/src/html/template/context.go > >> +index f7d4849..aaa7d08 100644 > >> +--- a/src/html/template/context.go > >> ++++ b/src/html/template/context.go > >> +@@ -6,6 +6,7 @@ package template > >> + > >> + import ( > >> + "fmt" > >> ++ "text/template/parse" > >> + ) > >> + > >> + // context describes the state an HTML parser must be in when it reaches > >> the > >> +@@ -22,6 +23,7 @@ type context struct { > >> + jsCtx jsCtx > >> + attr attr > >> + element element > >> ++ n parse.Node // for range break/continue > >> + err *Error > >> + } > >> + > >> +@@ -141,6 +143,8 @@ const ( > >> + // stateError is an infectious error state outside any valid > >> + // HTML/CSS/JS construct. > >> + stateError > >> ++ // stateDead marks unreachable code after a {{break}} or > >> {{continue}}. > >> ++ stateDead > >> + ) > >> + > >> + // isComment is true for any state that contains content meant for > >> template > >> +diff --git a/src/html/template/escape.go b/src/html/template/escape.go > >> +index 8739735..6dea79c 100644 > >> +--- a/src/html/template/escape.go > >> ++++ b/src/html/template/escape.go > >> +@@ -97,6 +97,15 @@ type escaper struct { > >> + actionNodeEdits map[*parse.ActionNode][]string > >> + templateNodeEdits map[*parse.TemplateNode]string > >> + textNodeEdits map[*parse.TextNode][]byte > >> ++ // rangeContext holds context about the current range loop. > >> ++ rangeContext *rangeContext > >> ++} > >> ++ > >> ++// rangeContext holds information about the current range loop. > >> ++type rangeContext struct { > >> ++ outer *rangeContext // outer loop > >> ++ breaks []context // context at each break action > >> ++ continues []context // context at each continue action > >> + } > >> + > >> + // makeEscaper creates a blank escaper for the given set. > >> +@@ -109,6 +118,7 @@ func makeEscaper(n *nameSpace) escaper { > >> + map[*parse.ActionNode][]string{}, > >> + map[*parse.TemplateNode]string{}, > >> + map[*parse.TextNode][]byte{}, > >> ++ nil, > >> + } > >> + } > >> + > >> +@@ -124,8 +134,16 @@ func (e *escaper) escape(c context, n parse.Node) > >> context { > >> + switch n := n.(type) { > >> + case *parse.ActionNode: > >> + return e.escapeAction(c, n) > >> ++ case *parse.BreakNode: > >> ++ c.n = n > >> ++ e.rangeContext.breaks = append(e.rangeContext.breaks, c) > >> ++ return context{state: stateDead} > >> + case *parse.CommentNode: > >> + return c > >> ++ case *parse.ContinueNode: > >> ++ c.n = n > >> ++ e.rangeContext.continues = append(e.rangeContext.breaks, c) > >> ++ return context{state: stateDead} > >> + case *parse.IfNode: > >> + return e.escapeBranch(c, &n.BranchNode, "if") > >> + case *parse.ListNode: > >> +@@ -427,6 +445,12 @@ func join(a, b context, node parse.Node, nodeName > >> string) context { > >> + if b.state == stateError { > >> + return b > >> + } > >> ++ if a.state == stateDead { > >> ++ return b > >> ++ } > >> ++ if b.state == stateDead { > >> ++ return a > >> ++ } > >> + if a.eq(b) { > >> + return a > >> + } > >> +@@ -466,14 +490,27 @@ func join(a, b context, node parse.Node, nodeName > >> string) context { > >> + > >> + // escapeBranch escapes a branch template node: "if", "range" and "with". > >> + func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName > >> string) context { > >> ++ if nodeName == "range" { > >> ++ e.rangeContext = &rangeContext{outer: e.rangeContext} > >> ++ } > >> + c0 := e.escapeList(c, n.List) > >> +- if nodeName == "range" && c0.state != stateError { > >> ++ if nodeName == "range" { > >> ++ if c0.state != stateError { > >> ++ c0 = joinRange(c0, e.rangeContext) > >> ++ } > >> ++ e.rangeContext = e.rangeContext.outer > >> ++ if c0.state == stateError { > >> ++ return c0 > >> ++ } > >> ++ > >> + // The "true" branch of a "range" node can execute > >> multiple times. > >> + // We check that executing n.List once results in the same > >> context > >> + // as executing n.List twice. > >> ++ e.rangeContext = &rangeContext{outer: e.rangeContext} > >> + c1, _ := e.escapeListConditionally(c0, n.List, nil) > >> + c0 = join(c0, c1, n, nodeName) > >> + if c0.state == stateError { > >> ++ e.rangeContext = e.rangeContext.outer > >> + // Make clear that this is a problem on loop > >> re-entry > >> + // since developers tend to overlook that branch > >> when > >> + // debugging templates. > >> +@@ -481,11 +518,39 @@ func (e *escaper) escapeBranch(c context, n > >> *parse.BranchNode, nodeName string) > >> + c0.err.Description = "on range loop re-entry: " + > >> c0.err.Description > >> + return c0 > >> + } > >> ++ c0 = joinRange(c0, e.rangeContext) > >> ++ e.rangeContext = e.rangeContext.outer > >> ++ if c0.state == stateError { > >> ++ return c0 > >> ++ } > >> + } > >> + c1 := e.escapeList(c, n.ElseList) > >> + return join(c0, c1, n, nodeName) > >> + } > >> + > >> ++func joinRange(c0 context, rc *rangeContext) context { > >> ++ // Merge contexts at break and continue statements into overall > >> body context. > >> ++ // In theory we could treat breaks differently from continues, but > >> for now it is > >> ++ // enough to treat them both as going back to the start of the > >> loop (which may then stop). > >> ++ for _, c := range rc.breaks { > >> ++ c0 = join(c0, c, c.n, "range") > >> ++ if c0.state == stateError { > >> ++ c0.err.Line = c.n.(*parse.BreakNode).Line > >> ++ c0.err.Description = "at range loop break: " + > >> c0.err.Description > >> ++ return c0 > >> ++ } > >> ++ } > >> ++ for _, c := range rc.continues { > >> ++ c0 = join(c0, c, c.n, "range") > >> ++ if c0.state == stateError { > >> ++ c0.err.Line = c.n.(*parse.ContinueNode).Line > >> ++ c0.err.Description = "at range loop continue: " + > >> c0.err.Description > >> ++ return c0 > >> ++ } > >> ++ } > >> ++ return c0 > >> ++} > >> ++ > >> + // escapeList escapes a list template node. > >> + func (e *escaper) escapeList(c context, n *parse.ListNode) context { > >> + if n == nil { > >> +@@ -493,6 +558,9 @@ func (e *escaper) escapeList(c context, n > >> *parse.ListNode) context { > >> + } > >> + for _, m := range n.Nodes { > >> + c = e.escape(c, m) > >> ++ if c.state == stateDead { > >> ++ break > >> ++ } > >> + } > >> + return c > >> + } > >> +@@ -503,6 +571,7 @@ func (e *escaper) escapeList(c context, n > >> *parse.ListNode) context { > >> + // which is the same as whether e was updated. > >> + func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, > >> filter func(*escaper, context) bool) (context, bool) { > >> + e1 := makeEscaper(e.ns) > >> ++ e1.rangeContext = e.rangeContext > >> + // Make type inferences available to f. > >> + for k, v := range e.output { > >> + e1.output[k] = v > >> +diff --git a/src/html/template/escape_test.go > >> b/src/html/template/escape_test.go > >> +index c709660..fa2b84a 100644 > >> +--- a/src/html/template/escape_test.go > >> ++++ b/src/html/template/escape_test.go > >> +@@ -920,6 +920,22 @@ func TestErrors(t *testing.T) { > >> + "<a href='/foo?{{range > >> .Items}}&{{.K}}={{.V}}{{end}}'>", > >> + "", > >> + }, > >> ++ { > >> ++ "{{range .Items}}<a{{if .X}}{{end}}>{{end}}", > >> ++ "", > >> ++ }, > >> ++ { > >> ++ "{{range .Items}}<a{{if > >> .X}}{{end}}>{{continue}}{{end}}", > >> ++ "", > >> ++ }, > >> ++ { > >> ++ "{{range .Items}}<a{{if > >> .X}}{{end}}>{{break}}{{end}}", > >> ++ "", > >> ++ }, > >> ++ { > >> ++ "{{range .Items}}<a{{if .X}}{{end}}>{{if > >> .X}}{{break}}{{end}}{{end}}", > >> ++ "", > >> ++ }, > >> + // Error cases. > >> + { > >> + "{{if .Cond}}<a{{end}}", > >> +@@ -956,6 +972,14 @@ func TestErrors(t *testing.T) { > >> + "z:2:8: on range loop re-entry: {{range}} > >> branches", > >> + }, > >> + { > >> ++ "{{range .Items}}<a{{if > >> .X}}{{break}}{{end}}>{{end}}", > >> ++ "z:1:29: at range loop break: {{range}} branches > >> end in different contexts", > >> ++ }, > >> ++ { > >> ++ "{{range .Items}}<a{{if > >> .X}}{{continue}}{{end}}>{{end}}", > >> ++ "z:1:29: at range loop continue: {{range}} > >> branches end in different contexts", > >> ++ }, > >> ++ { > >> + "<a b=1 c={{.H}}", > >> + "z: ends in a non-text context: {stateAttr > >> delimSpaceOrTagEnd", > >> + }, > >> +diff --git a/src/text/template/doc.go b/src/text/template/doc.go > >> +index 7b30294..0228b15 100644 > >> +--- a/src/text/template/doc.go > >> ++++ b/src/text/template/doc.go > >> +@@ -112,6 +112,14 @@ data, defined in detail in the corresponding > >> sections that follow. > >> + T0 is executed; otherwise, dot is set to the successive > >> elements > >> + of the array, slice, or map and T1 is executed. > >> + > >> ++ {{break}} > >> ++ The innermost {{range pipeline}} loop is ended early, > >> stopping the > >> ++ current iteration and bypassing all remaining iterations. > >> ++ > >> ++ {{continue}} > >> ++ The current iteration of the innermost {{range pipeline}} > >> loop is > >> ++ stopped, and the loop starts the next iteration. > >> ++ > >> + {{template "name"}} > >> + The template with the specified name is executed with nil > >> data. > >> + > >> +diff --git a/src/text/template/exec.go b/src/text/template/exec.go > >> +index 7ac5175..6cb140a 100644 > >> +--- a/src/text/template/exec.go > >> ++++ b/src/text/template/exec.go > >> +@@ -5,6 +5,7 @@ > >> + package template > >> + > >> + import ( > >> ++ "errors" > >> + "fmt" > >> + "internal/fmtsort" > >> + "io" > >> +@@ -244,6 +245,12 @@ func (t *Template) DefinedTemplates() string { > >> + return b.String() > >> + } > >> + > >> ++// Sentinel errors for use with panic to signal early exits from range > >> loops. > >> ++var ( > >> ++ walkBreak = errors.New("break") > >> ++ walkContinue = errors.New("continue") > >> ++) > >> ++ > >> + // Walk functions step through the major pieces of the template > >> structure, > >> + // generating output as they go. > >> + func (s *state) walk(dot reflect.Value, node parse.Node) { > >> +@@ -256,7 +263,11 @@ func (s *state) walk(dot reflect.Value, node > >> parse.Node) { > >> + if len(node.Pipe.Decl) == 0 { > >> + s.printValue(node, val) > >> + } > >> ++ case *parse.BreakNode: > >> ++ panic(walkBreak) > >> + case *parse.CommentNode: > >> ++ case *parse.ContinueNode: > >> ++ panic(walkContinue) > >> + case *parse.IfNode: > >> + s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, > >> node.ElseList) > >> + case *parse.ListNode: > >> +@@ -335,6 +346,11 @@ func isTrue(val reflect.Value) (truth, ok bool) { > >> + > >> + func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { > >> + s.at(r) > >> ++ defer func() { > >> ++ if r := recover(); r != nil && r != walkBreak { > >> ++ panic(r) > >> ++ } > >> ++ }() > >> + defer s.pop(s.mark()) > >> + val, _ := indirect(s.evalPipeline(dot, r.Pipe)) > >> + // mark top of stack before any variables in the body are pushed. > >> +@@ -348,8 +364,14 @@ func (s *state) walkRange(dot reflect.Value, r > >> *parse.RangeNode) { > >> + if len(r.Pipe.Decl) > 1 { > >> + s.setTopVar(2, index) > >> + } > >> ++ defer s.pop(mark) > >> ++ defer func() { > >> ++ // Consume panic(walkContinue) > >> ++ if r := recover(); r != nil && r != walkContinue { > >> ++ panic(r) > >> ++ } > >> ++ }() > >> + s.walk(elem, r.List) > >> +- s.pop(mark) > >> + } > >> + switch val.Kind() { > >> + case reflect.Array, reflect.Slice: > >> +diff --git a/src/text/template/exec_test.go > >> b/src/text/template/exec_test.go > >> +index 3309b33..a639f44 100644 > >> +--- a/src/text/template/exec_test.go > >> ++++ b/src/text/template/exec_test.go > >> +@@ -563,6 +563,8 @@ var execTests = []execTest{ > >> + {"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", > >> tVal, true}, > >> + {"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", > >> "-3--4--5-", tVal, true}, > >> + {"range empty else", "{{range > >> .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, > >> ++ {"range []int break else", "{{range > >> .SI}}-{{.}}-{{break}}NOTREACHED{{else}}EMPTY{{end}}", "-3-", tVal, true}, > >> ++ {"range []int continue else", "{{range > >> .SI}}-{{.}}-{{continue}}NOTREACHED{{else}}EMPTY{{end}}", "-3--4--5-", > >> tVal, true}, > >> + {"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", > >> tVal, true}, > >> + {"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", > >> "-20--21--22-", tVal, true}, > >> + {"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, > >> true}, > >> +diff --git a/src/text/template/parse/lex.go > >> b/src/text/template/parse/lex.go > >> +index 6784071..95e3377 100644 > >> +--- a/src/text/template/parse/lex.go > >> ++++ b/src/text/template/parse/lex.go > >> +@@ -62,6 +62,8 @@ const ( > >> + // Keywords appear after all the rest. > >> + itemKeyword // used only to delimit the keywords > >> + itemBlock // block keyword > >> ++ itemBreak // break keyword > >> ++ itemContinue // continue keyword > >> + itemDot // the cursor, spelled '.' > >> + itemDefine // define keyword > >> + itemElse // else keyword > >> +@@ -76,6 +78,8 @@ const ( > >> + var key = map[string]itemType{ > >> + ".": itemDot, > >> + "block": itemBlock, > >> ++ "break": itemBreak, > >> ++ "continue": itemContinue, > >> + "define": itemDefine, > >> + "else": itemElse, > >> + "end": itemEnd, > >> +@@ -119,6 +123,8 @@ type lexer struct { > >> + parenDepth int // nesting depth of ( ) exprs > >> + line int // 1+number of newlines seen > >> + startLine int // start line of this item > >> ++ breakOK bool // break keyword allowed > >> ++ continueOK bool // continue keyword allowed > >> + } > >> + > >> + // next returns the next rune in the input. > >> +@@ -461,7 +467,12 @@ Loop: > >> + } > >> + switch { > >> + case key[word] > itemKeyword: > >> +- l.emit(key[word]) > >> ++ item := key[word] > >> ++ if item == itemBreak && !l.breakOK || item > >> == itemContinue && !l.continueOK { > >> ++ l.emit(itemIdentifier) > >> ++ } else { > >> ++ l.emit(item) > >> ++ } > >> + case word[0] == '.': > >> + l.emit(itemField) > >> + case word == "true", word == "false": > >> +diff --git a/src/text/template/parse/lex_test.go > >> b/src/text/template/parse/lex_test.go > >> +index 6510eed..df6aabf 100644 > >> +--- a/src/text/template/parse/lex_test.go > >> ++++ b/src/text/template/parse/lex_test.go > >> +@@ -35,6 +35,8 @@ var itemName = map[itemType]string{ > >> + // keywords > >> + itemDot: ".", > >> + itemBlock: "block", > >> ++ itemBreak: "break", > >> ++ itemContinue: "continue", > >> + itemDefine: "define", > >> + itemElse: "else", > >> + itemIf: "if", > >> +diff --git a/src/text/template/parse/node.go > >> b/src/text/template/parse/node.go > >> +index a9dad5e..c398da0 100644 > >> +--- a/src/text/template/parse/node.go > >> ++++ b/src/text/template/parse/node.go > >> +@@ -71,6 +71,8 @@ const ( > >> + NodeVariable // A $ variable. > >> + NodeWith // A with action. > >> + NodeComment // A comment. > >> ++ NodeBreak // A break action. > >> ++ NodeContinue // A continue action. > >> + ) > >> + > >> + // Nodes. > >> +@@ -907,6 +909,40 @@ func (i *IfNode) Copy() Node { > >> + return i.tr.newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), > >> i.List.CopyList(), i.ElseList.CopyList()) > >> + } > >> + > >> ++// BreakNode represents a {{break}} action. > >> ++type BreakNode struct { > >> ++ tr *Tree > >> ++ NodeType > >> ++ Pos > >> ++ Line int > >> ++} > >> ++ > >> ++func (t *Tree) newBreak(pos Pos, line int) *BreakNode { > >> ++ return &BreakNode{tr: t, NodeType: NodeBreak, Pos: pos, Line: line} > >> ++} > >> ++ > >> ++func (b *BreakNode) Copy() Node { return > >> b.tr.newBreak(b.Pos, b.Line) } > >> ++func (b *BreakNode) String() string { return "{{break}}" } > >> ++func (b *BreakNode) tree() *Tree { return b.tr } > >> ++func (b *BreakNode) writeTo(sb *strings.Builder) { > >> sb.WriteString("{{break}}") } > >> ++ > >> ++// ContinueNode represents a {{continue}} action. > >> ++type ContinueNode struct { > >> ++ tr *Tree > >> ++ NodeType > >> ++ Pos > >> ++ Line int > >> ++} > >> ++ > >> ++func (t *Tree) newContinue(pos Pos, line int) *ContinueNode { > >> ++ return &ContinueNode{tr: t, NodeType: NodeContinue, Pos: pos, > >> Line: line} > >> ++} > >> ++ > >> ++func (c *ContinueNode) Copy() Node { return > >> c.tr.newContinue(c.Pos, c.Line) } > >> ++func (c *ContinueNode) String() string { return > >> "{{continue}}" } > >> ++func (c *ContinueNode) tree() *Tree { return c.tr } > >> ++func (c *ContinueNode) writeTo(sb *strings.Builder) { > >> sb.WriteString("{{continue}}") } > >> ++ > >> + // RangeNode represents a {{range}} action and its commands. > >> + type RangeNode struct { > >> + BranchNode > >> +diff --git a/src/text/template/parse/parse.go > >> b/src/text/template/parse/parse.go > >> +index 5e6e512..7f78b56 100644 > >> +--- a/src/text/template/parse/parse.go > >> ++++ b/src/text/template/parse/parse.go > >> +@@ -31,6 +31,7 @@ type Tree struct { > >> + vars []string // variables defined at the moment. > >> + treeSet map[string]*Tree > >> + actionLine int // line of left delim starting action > >> ++ rangeDepth int > >> + mode Mode > >> + } > >> + > >> +@@ -223,6 +224,8 @@ func (t *Tree) startParse(funcs > >> []map[string]interface{}, lex *lexer, treeSet ma > >> + t.vars = []string{"$"} > >> + t.funcs = funcs > >> + t.treeSet = treeSet > >> ++ lex.breakOK = !t.hasFunction("break") > >> ++ lex.continueOK = !t.hasFunction("continue") > >> + } > >> + > >> + // stopParse terminates parsing. > >> +@@ -385,6 +388,10 @@ func (t *Tree) action() (n Node) { > >> + switch token := t.nextNonSpace(); token.typ { > >> + case itemBlock: > >> + return t.blockControl() > >> ++ case itemBreak: > >> ++ return t.breakControl(token.pos, token.line) > >> ++ case itemContinue: > >> ++ return t.continueControl(token.pos, token.line) > >> + case itemElse: > >> + return t.elseControl() > >> + case itemEnd: > >> +@@ -404,6 +411,32 @@ func (t *Tree) action() (n Node) { > >> + return t.newAction(token.pos, token.line, t.pipeline("command", > >> itemRightDelim)) > >> + } > >> + > >> ++// Break: > >> ++// {{break}} > >> ++// Break keyword is past. > >> ++func (t *Tree) breakControl(pos Pos, line int) Node { > >> ++ if token := t.next(); token.typ != itemRightDelim { > >> ++ t.unexpected(token, "in {{break}}") > >> ++ } > >> ++ if t.rangeDepth == 0 { > >> ++ t.errorf("{{break}} outside {{range}}") > >> ++ } > >> ++ return t.newBreak(pos, line) > >> ++} > >> ++ > >> ++// Continue: > >> ++// {{continue}} > >> ++// Continue keyword is past. > >> ++func (t *Tree) continueControl(pos Pos, line int) Node { > >> ++ if token := t.next(); token.typ != itemRightDelim { > >> ++ t.unexpected(token, "in {{continue}}") > >> ++ } > >> ++ if t.rangeDepth == 0 { > >> ++ t.errorf("{{continue}} outside {{range}}") > >> ++ } > >> ++ return t.newContinue(pos, line) > >> ++} > >> ++ > >> + // Pipeline: > >> + // declarations? command ('|' command)* > >> + func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) { > >> +@@ -479,8 +512,14 @@ func (t *Tree) checkPipeline(pipe *PipeNode, context > >> string) { > >> + func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, > >> line int, pipe *PipeNode, list, elseList *ListNode) { > >> + defer t.popVars(len(t.vars)) > >> + pipe = t.pipeline(context, itemRightDelim) > >> ++ if context == "range" { > >> ++ t.rangeDepth++ > >> ++ } > >> + var next Node > >> + list, next = t.itemList() > >> ++ if context == "range" { > >> ++ t.rangeDepth-- > >> ++ } > >> + switch next.Type() { > >> + case nodeEnd: //done > >> + case nodeElse: > >> +@@ -522,7 +561,8 @@ func (t *Tree) ifControl() Node { > >> + // {{range pipeline}} itemList {{else}} itemList {{end}} > >> + // Range keyword is past. > >> + func (t *Tree) rangeControl() Node { > >> +- return t.newRange(t.parseControl(false, "range")) > >> ++ r := t.newRange(t.parseControl(false, "range")) > >> ++ return r > >> + } > >> + > >> + // With: > >> +diff --git a/src/text/template/parse/parse_test.go > >> b/src/text/template/parse/parse_test.go > >> +index 220f984..ba45636 100644 > >> +--- a/src/text/template/parse/parse_test.go > >> ++++ b/src/text/template/parse/parse_test.go > >> +@@ -230,6 +230,10 @@ var parseTests = []parseTest{ > >> + `{{range $x := .SI}}{{.}}{{end}}`}, > >> + {"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError, > >> + `{{range $x, $y := .SI}}{{.}}{{end}}`}, > >> ++ {"range with break", "{{range .SI}}{{.}}{{break}}{{end}}", noError, > >> ++ `{{range .SI}}{{.}}{{break}}{{end}}`}, > >> ++ {"range with continue", "{{range .SI}}{{.}}{{continue}}{{end}}", > >> noError, > >> ++ `{{range .SI}}{{.}}{{continue}}{{end}}`}, > >> + {"constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", > >> noError, > >> + `{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`}, > >> + {"template", "{{template `x`}}", noError, > >> +@@ -279,6 +283,10 @@ var parseTests = []parseTest{ > >> + {"adjacent args", "{{printf 3`x`}}", hasError, ""}, > >> + {"adjacent args with .", "{{printf `x`.}}", hasError, ""}, > >> + {"extra end after if", "{{if .X}}a{{else if .Y}}b{{end}}{{end}}", > >> hasError, ""}, > >> ++ {"break outside range", "{{range .}}{{end}} {{break}}", hasError, > >> ""}, > >> ++ {"continue outside range", "{{range .}}{{end}} {{continue}}", > >> hasError, ""}, > >> ++ {"break in range else", "{{range .}}{{else}}{{break}}{{end}}", > >> hasError, ""}, > >> ++ {"continue in range else", "{{range > >> .}}{{else}}{{continue}}{{end}}", hasError, ""}, > >> + // Other kinds of assignments and operators aren't available yet. > >> + {"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"}, > >> + {"bug0b", "{{$x += 1}}{{$x}}", hasError, ""}, > >> +-- > >> +2.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 > >> similarity index 53% > >> rename from meta/recipes-devtools/go/go-1.14/CVE-2023-24538-3.patch > >> rename to 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 @@ > >> From 16f4882984569f179d73967c9eee679bb9b098c5 Mon Sep 17 00:00:00 2001 > >> From: Roland Shoemaker <bracew...@google.com> > >> Date: Mon, 20 Mar 2023 11:01:13 -0700 > >> -Subject: [PATCH 3/3] html/template: disallow actions in JS template > >> literals > >> +Subject: [PATCH 6/6] html/template: disallow actions in JS template > >> literals > >> > >> ECMAScript 6 introduced template literals[0][1] which are delimited with > >> backticks. These need to be escaped in a similar fashion to the > >> @@ -52,12 +52,15 @@ CVE: CVE-2023-24538 > >> Signed-off-by: Shubham Kulkarni <skulka...@mvista.com> > >> --- > >> src/html/template/context.go | 2 ++ > >> - src/html/template/error.go | 13 +++++++++++++ > >> - src/html/template/escape.go | 11 +++++++++++ > >> + src/html/template/error.go | 13 ++++++++ > >> + src/html/template/escape.go | 11 +++++++ > >> + src/html/template/escape_test.go | 66 > >> ++++++++++++++++++++++----------------- > >> src/html/template/js.go | 2 ++ > >> - src/html/template/jsctx_string.go | 9 +++++++++ > >> - src/html/template/transition.go | 7 ++++++- > >> - 6 files changed, 43 insertions(+), 1 deletion(-) > >> + src/html/template/js_test.go | 2 +- > >> + src/html/template/jsctx_string.go | 9 ++++++ > >> + src/html/template/state_string.go | 37 ++++++++++++++++++++-- > >> + src/html/template/transition.go | 7 ++++- > >> + 9 files changed, 116 insertions(+), 33 deletions(-) > >> > >> diff --git a/src/html/template/context.go b/src/html/template/context.go > >> index f7d4849..0b65313 100644 > >> @@ -125,6 +128,104 @@ index f12dafa..29ca5b3 100644 > >> case stateJSRegexp: > >> s = append(s, "_html_template_jsregexpescaper") > >> case stateCSS: > >> +diff --git a/src/html/template/escape_test.go > >> b/src/html/template/escape_test.go > >> +index fa2b84a..1b150e9 100644 > >> +--- a/src/html/template/escape_test.go > >> ++++ b/src/html/template/escape_test.go > >> +@@ -681,35 +681,31 @@ func TestEscape(t *testing.T) { > >> + } > >> + > >> + for _, test := range tests { > >> +- tmpl := New(test.name) > >> +- tmpl = Must(tmpl.Parse(test.input)) > >> +- // Check for bug 6459: Tree field was not set in Parse. > >> +- if tmpl.Tree != tmpl.text.Tree { > >> +- t.Errorf("%s: tree not set properly", test.name) > >> +- continue > >> +- } > >> +- b := new(bytes.Buffer) > >> +- if err := tmpl.Execute(b, data); err != nil { > >> +- t.Errorf("%s: template execution failed: %s", > >> test.name, err) > >> +- continue > >> +- } > >> +- if w, g := test.output, b.String(); w != g { > >> +- t.Errorf("%s: escaped output: > >> want\n\t%q\ngot\n\t%q", test.name, w, g) > >> +- continue > >> +- } > >> +- b.Reset() > >> +- if err := tmpl.Execute(b, pdata); err != nil { > >> +- t.Errorf("%s: template execution failed for > >> pointer: %s", test.name, err) > >> +- continue > >> +- } > >> +- if w, g := test.output, b.String(); w != g { > >> +- t.Errorf("%s: escaped output for pointer: > >> want\n\t%q\ngot\n\t%q", test.name, w, g) > >> +- continue > >> +- } > >> +- if tmpl.Tree != tmpl.text.Tree { > >> +- t.Errorf("%s: tree mismatch", test.name) > >> +- continue > >> +- } > >> ++ t.Run(test.name, func(t *testing.T) { > >> ++ tmpl := New(test.name) > >> ++ tmpl = Must(tmpl.Parse(test.input)) > >> ++ // Check for bug 6459: Tree field was not set in > >> Parse. > >> ++ if tmpl.Tree != tmpl.text.Tree { > >> ++ t.Fatalf("%s: tree not set properly", > >> test.name) > >> ++ } > >> ++ b := new(strings.Builder) > >> ++ if err := tmpl.Execute(b, data); err != nil { > >> ++ t.Fatalf("%s: template execution failed: > >> %s", test.name, err) > >> ++ } > >> ++ if w, g := test.output, b.String(); w != g { > >> ++ t.Fatalf("%s: escaped output: > >> want\n\t%q\ngot\n\t%q", test.name, w, g) > >> ++ } > >> ++ b.Reset() > >> ++ if err := tmpl.Execute(b, pdata); err != nil { > >> ++ t.Fatalf("%s: template execution failed > >> for pointer: %s", test.name, err) > >> ++ } > >> ++ if w, g := test.output, b.String(); w != g { > >> ++ t.Fatalf("%s: escaped output for pointer: > >> want\n\t%q\ngot\n\t%q", test.name, w, g) > >> ++ } > >> ++ if tmpl.Tree != tmpl.text.Tree { > >> ++ t.Fatalf("%s: tree mismatch", test.name) > >> ++ } > >> ++ }) > >> + } > >> + } > >> + > >> +@@ -936,6 +932,10 @@ func TestErrors(t *testing.T) { > >> + "{{range .Items}}<a{{if .X}}{{end}}>{{if > >> .X}}{{break}}{{end}}{{end}}", > >> + "", > >> + }, > >> ++ { > >> ++ "<script>var a = `${a+b}`</script>`", > >> ++ "", > >> ++ }, > >> + // Error cases. > >> + { > >> + "{{if .Cond}}<a{{end}}", > >> +@@ -1082,6 +1082,10 @@ func TestErrors(t *testing.T) { > >> + // html is allowed since it is the last command in > >> the pipeline, but urlquery is not. > >> + `predefined escaper "urlquery" disallowed in > >> template`, > >> + }, > >> ++ { > >> ++ "<script>var tmpl = `asd {{.}}`;</script>", > >> ++ `{{.}} appears in a JS template literal`, > >> ++ }, > >> + } > >> + for _, test := range tests { > >> + buf := new(bytes.Buffer) > >> +@@ -1304,6 +1308,10 @@ func TestEscapeText(t *testing.T) { > >> + context{state: stateJSSqStr, delim: > >> delimDoubleQuote, attr: attrScript}, > >> + }, > >> + { > >> ++ "<a onclick=\"`foo", > >> ++ context{state: stateJSBqStr, delim: > >> delimDoubleQuote, attr: attrScript}, > >> ++ }, > >> ++ { > >> + `<A ONCLICK="'`, > >> + context{state: stateJSSqStr, delim: > >> delimDoubleQuote, attr: attrScript}, > >> + }, > >> diff --git a/src/html/template/js.go b/src/html/template/js.go > >> index ea9c183..b888eaf 100644 > >> --- a/src/html/template/js.go > >> @@ -145,6 +246,19 @@ index ea9c183..b888eaf 100644 > >> '+': `\u002b`, > >> '/': `\/`, > >> '<': `\u003c`, > >> +diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go > >> +index d7ee47b..7d963ae 100644 > >> +--- a/src/html/template/js_test.go > >> ++++ b/src/html/template/js_test.go > >> +@@ -292,7 +292,7 @@ func TestEscapersOnLower7AndSelectHighCodepoints(t > >> *testing.T) { > >> + `0123456789:;\u003c=\u003e?` + > >> + `@ABCDEFGHIJKLMNO` + > >> + `PQRSTUVWXYZ[\\]^_` + > >> +- "`abcdefghijklmno" + > >> ++ "\\u0060abcdefghijklmno" + > >> + "pqrstuvwxyz{|}~\u007f" + > >> + > >> "\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E", > >> + }, > >> diff --git a/src/html/template/jsctx_string.go > >> b/src/html/template/jsctx_string.go > >> index dd1d87e..2394893 100644 > >> --- a/src/html/template/jsctx_string.go > >> @@ -165,6 +279,55 @@ index dd1d87e..2394893 100644 > >> const _jsCtx_name = "jsCtxRegexpjsCtxDivOpjsCtxUnknown" > >> > >> var _jsCtx_index = [...]uint8{0, 11, 21, 33} > >> +diff --git a/src/html/template/state_string.go > >> b/src/html/template/state_string.go > >> +index 05104be..6fb1a6e 100644 > >> +--- a/src/html/template/state_string.go > >> ++++ b/src/html/template/state_string.go > >> +@@ -4,9 +4,42 @@ package template > >> + > >> + import "strconv" > >> + > >> +-const _state_name = > >> "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError" > >> ++func _() { > >> ++ // An "invalid array index" compiler error signifies that the > >> constant values have changed. > >> ++ // Re-run the stringer command to generate them again. > >> ++ var x [1]struct{} > >> ++ _ = x[stateText-0] > >> ++ _ = x[stateTag-1] > >> ++ _ = x[stateAttrName-2] > >> ++ _ = x[stateAfterName-3] > >> ++ _ = x[stateBeforeValue-4] > >> ++ _ = x[stateHTMLCmt-5] > >> ++ _ = x[stateRCDATA-6] > >> ++ _ = x[stateAttr-7] > >> ++ _ = x[stateURL-8] > >> ++ _ = x[stateSrcset-9] > >> ++ _ = x[stateJS-10] > >> ++ _ = x[stateJSDqStr-11] > >> ++ _ = x[stateJSSqStr-12] > >> ++ _ = x[stateJSBqStr-13] > >> ++ _ = x[stateJSRegexp-14] > >> ++ _ = x[stateJSBlockCmt-15] > >> ++ _ = x[stateJSLineCmt-16] > >> ++ _ = x[stateCSS-17] > >> ++ _ = x[stateCSSDqStr-18] > >> ++ _ = x[stateCSSSqStr-19] > >> ++ _ = x[stateCSSDqURL-20] > >> ++ _ = x[stateCSSSqURL-21] > >> ++ _ = x[stateCSSURL-22] > >> ++ _ = x[stateCSSBlockCmt-23] > >> ++ _ = x[stateCSSLineCmt-24] > >> ++ _ = x[stateError-25] > >> ++ _ = x[stateDead-26] > >> ++} > >> ++ > >> ++const _state_name = > >> "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" > >> + > >> +-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} > >> ++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} > >> + > >> + func (i state) String() string { > >> + if i >= state(len(_state_index)-1) { > >> diff --git a/src/html/template/transition.go > >> b/src/html/template/transition.go > >> index 06df679..92eb351 100644 > >> --- 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 <sdo...@mvista.com> > >> src/html/template/context.go | 6 ++- > >> src/html/template/escape.go | 5 +- > >> src/html/template/escape_test.go | 10 ++++ > >> - src/html/template/state_string.go | 4 +- > >> + src/html/template/state_string.go | 26 +++++----- > >> src/html/template/transition.go | 80 ++++++++++++++++++++----------- > >> - 5 files changed, 72 insertions(+), 33 deletions(-) > >> + 5 files changed, 84 insertions(+), 43 deletions(-) > >> > >> diff --git a/src/html/template/context.go b/src/html/template/context.go > >> index 0b65313..4eb7891 100644 > >> @@ -105,14 +105,38 @@ diff --git a/src/html/template/state_string.go > >> b/src/html/template/state_string. > >> index 05104be..b5cfe70 100644 > >> --- a/src/html/template/state_string.go > >> +++ b/src/html/template/state_string.go > >> -@@ -4,9 +4,9 @@ package template > >> - > >> - import "strconv" > >> +@@ -25,21 +25,23 @@ func _() { > >> + _ = x[stateJSRegexp-14] > >> + _ = x[stateJSBlockCmt-15] > >> + _ = x[stateJSLineCmt-16] > >> +- _ = x[stateCSS-17] > >> +- _ = x[stateCSSDqStr-18] > >> +- _ = x[stateCSSSqStr-19] > >> +- _ = x[stateCSSDqURL-20] > >> +- _ = x[stateCSSSqURL-21] > >> +- _ = x[stateCSSURL-22] > >> +- _ = x[stateCSSBlockCmt-23] > >> +- _ = x[stateCSSLineCmt-24] > >> +- _ = x[stateError-25] > >> +- _ = x[stateDead-26] > >> ++ _ = x[stateJSHTMLOpenCmt-17] > >> ++ _ = x[stateJSHTMLCloseCmt-18] > >> ++ _ = x[stateCSS-19] > >> ++ _ = x[stateCSSDqStr-20] > >> ++ _ = x[stateCSSSqStr-21] > >> ++ _ = x[stateCSSDqURL-22] > >> ++ _ = x[stateCSSSqURL-23] > >> ++ _ = x[stateCSSURL-24] > >> ++ _ = x[stateCSSBlockCmt-25] > >> ++ _ = x[stateCSSLineCmt-26] > >> ++ _ = x[stateError-27] > >> ++ _ = x[stateDead-28] > >> + } > >> > >> --const _state_name = > >> "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError" > >> +-const _state_name = > >> "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" > >> +const _state_name = > >> "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" > >> > >> --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} > >> +-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} > >> +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} > >> > >> func (i state) String() string { > >> -- > >> 2.42.0 > >>
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#188416): https://lists.openembedded.org/g/openembedded-core/message/188416 Mute This Topic: https://lists.openembedded.org/mt/101664364/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-