On Tue, Oct 3, 2023 at 3:49 AM Shubham Kulkarni <skulka...@mvista.com> wrote: > > Hi Steve, > > I have recreated the patch from scratch for dunfell and sent it as v4 - > https://lists.openembedded.org/g/openembedded-core/message/188639 > The issue in v3 might be due to whitespaces. But v4 should be good.
Sorry, it still fails: Applying: go: Update fix for CVE-2023-24538 & CVE-2023-39318 error: corrupt patch at line 1074 error: could not build fake ancestor To debug, try downloading your patch from the list and then applying it to the dunfell HEAD. Alternatively you could download from patchworks: https://patchwork.yoctoproject.org/project/oe-core/patch/20231003134246.24630-1-skulka...@mvista.com/ Steve > On Sat, Sep 30, 2023 at 9:11 PM Shubham Kulkarni via lists.openembedded.org > <skulkarni=mvista....@lists.openembedded.org> wrote: >> >> Apologies Steve, >> >> I will look into the issue and send a new patch for Dunfell. It worked for >> me on my machine. Maybe something I missed. >> >> Thanks, >> Shubham Kulkarni >> >> On Sat, Sep 30, 2023 at 8:02 AM Steve Sakoman <st...@sakoman.com> wrote: >>> >>> Sorry, this patch doesn't apply: >>> >>> Applying: go: Update fix for CVE-2023-24538 & CVE-2023-39318 >>> error: corrupt patch at line 478 >>> error: could not build fake ancestor >>> Patch failed at 0001 go: Update fix for CVE-2023-24538 & CVE-2023-39318 >>> >>> Steve >>> >>> On Fri, Sep 29, 2023 at 9:21 AM Shubham Kulkarni via >>> lists.openembedded.org <skulkarni=mvista....@lists.openembedded.org> >>> 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 (#188644): https://lists.openembedded.org/g/openembedded-core/message/188644 Mute This Topic: https://lists.openembedded.org/mt/101664679/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-