diff options
| author | Shubham Kulkarni <skulkarni@mvista.com> | 2023-09-30 00:50:33 +0530 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2023-10-05 15:48:49 -1000 |
| commit | 74b22a5e918b8d3a71748880e9ab2179f6486c71 (patch) | |
| tree | 34e9308936273262d3e41baf73dff44bed960543 | |
| parent | 25073f9c0e0ca7ecfe8f38bf620147314c0d3ddc (diff) | |
| download | poky-74b22a5e918b8d3a71748880e9ab2179f6486c71.tar.gz | |
go: Update fix for CVE-2023-24538 & CVE-2023-39318
Add missing files in fix for CVE-2023-24538 & CVE-2023-39318
Upstream Link -
CVE-2023-24538: https://github.com/golang/go/commit/b1e3ecfa06b67014429a197ec5e134ce4303ad9b
CVE-2023-39318: https://github.com/golang/go/commit/023b542edf38e2a1f87fcefb9f75ff2f99401b4c
(From OE-Core rev: 0d8f7062d4fb5525f34427b1a7304f165bee0cfc)
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
| -rw-r--r-- | meta/recipes-devtools/go/go-1.17.13.inc | 3 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go-1.18/CVE-2023-24538_1.patch | 597 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go-1.18/CVE-2023-24538_2.patch (renamed from meta/recipes-devtools/go/go-1.18/CVE-2023-24538.patch) | 175 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go-1.21/CVE-2023-39318.patch | 44 |
4 files changed, 802 insertions, 17 deletions
diff --git a/meta/recipes-devtools/go/go-1.17.13.inc b/meta/recipes-devtools/go/go-1.17.13.inc index ed2645bc12..461819d80f 100644 --- a/meta/recipes-devtools/go/go-1.17.13.inc +++ b/meta/recipes-devtools/go/go-1.17.13.inc | |||
| @@ -29,7 +29,8 @@ SRC_URI += "\ | |||
| 29 | file://CVE-2022-41722.patch \ | 29 | file://CVE-2022-41722.patch \ |
| 30 | file://CVE-2023-24537.patch \ | 30 | file://CVE-2023-24537.patch \ |
| 31 | file://CVE-2023-24534.patch \ | 31 | file://CVE-2023-24534.patch \ |
| 32 | file://CVE-2023-24538.patch \ | 32 | file://CVE-2023-24538_1.patch \ |
| 33 | file://CVE-2023-24538_2.patch \ | ||
| 33 | file://CVE-2023-24540.patch \ | 34 | file://CVE-2023-24540.patch \ |
| 34 | file://CVE-2023-24539.patch \ | 35 | file://CVE-2023-24539.patch \ |
| 35 | file://CVE-2023-29404.patch \ | 36 | file://CVE-2023-29404.patch \ |
diff --git a/meta/recipes-devtools/go/go-1.18/CVE-2023-24538_1.patch b/meta/recipes-devtools/go/go-1.18/CVE-2023-24538_1.patch new file mode 100644 index 0000000000..bb0a416f46 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.18/CVE-2023-24538_1.patch | |||
| @@ -0,0 +1,597 @@ | |||
| 1 | From b1e4e8ec7e946ff2d3bb37ac99c5468ceb49c362 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Russ Cox <rsc@golang.org> | ||
| 3 | Date: Thu, 20 May 2021 12:46:33 -0400 | ||
| 4 | Subject: [PATCH 1/2] html/template, text/template: implement break and | ||
| 5 | continue for range loops | ||
| 6 | |||
| 7 | Break and continue for range loops was accepted as a proposal in June 2017. | ||
| 8 | It was implemented in CL 66410 (Oct 2017) | ||
| 9 | but then rolled back in CL 92155 (Feb 2018) | ||
| 10 | because html/template changes had not been implemented. | ||
| 11 | |||
| 12 | This CL reimplements break and continue in text/template | ||
| 13 | and then adds support for them in html/template as well. | ||
| 14 | |||
| 15 | Fixes #20531. | ||
| 16 | |||
| 17 | Change-Id: I05330482a976f1c078b4b49c2287bd9031bb7616 | ||
| 18 | Reviewed-on: https://go-review.googlesource.com/c/go/+/321491 | ||
| 19 | Trust: Russ Cox <rsc@golang.org> | ||
| 20 | Run-TryBot: Russ Cox <rsc@golang.org> | ||
| 21 | TryBot-Result: Go Bot <gobot@golang.org> | ||
| 22 | Reviewed-by: Rob Pike <r@golang.org> | ||
| 23 | |||
| 24 | Upstream-Status: Backport from https://github.com/golang/go/commit/d0dd26a88c019d54f22463daae81e785f5867565 | ||
| 25 | CVE: CVE-2023-24538 | ||
| 26 | Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> | ||
| 27 | --- | ||
| 28 | src/html/template/context.go | 4 ++ | ||
| 29 | src/html/template/escape.go | 71 ++++++++++++++++++++++++++++++++++- | ||
| 30 | src/html/template/escape_test.go | 24 ++++++++++++ | ||
| 31 | src/html/template/exec_test.go | 2 + | ||
| 32 | src/text/template/doc.go | 8 ++++ | ||
| 33 | src/text/template/exec.go | 24 +++++++++++- | ||
| 34 | src/text/template/exec_test.go | 2 + | ||
| 35 | src/text/template/parse/lex.go | 13 ++++++- | ||
| 36 | src/text/template/parse/lex_test.go | 2 + | ||
| 37 | src/text/template/parse/node.go | 36 ++++++++++++++++++ | ||
| 38 | src/text/template/parse/parse.go | 42 ++++++++++++++++++++- | ||
| 39 | src/text/template/parse/parse_test.go | 8 ++++ | ||
| 40 | 12 files changed, 232 insertions(+), 4 deletions(-) | ||
| 41 | |||
| 42 | diff --git a/src/html/template/context.go b/src/html/template/context.go | ||
| 43 | index f7d4849..aaa7d08 100644 | ||
| 44 | --- a/src/html/template/context.go | ||
| 45 | +++ b/src/html/template/context.go | ||
| 46 | @@ -6,6 +6,7 @@ package template | ||
| 47 | |||
| 48 | import ( | ||
| 49 | "fmt" | ||
| 50 | + "text/template/parse" | ||
| 51 | ) | ||
| 52 | |||
| 53 | // context describes the state an HTML parser must be in when it reaches the | ||
| 54 | @@ -22,6 +23,7 @@ type context struct { | ||
| 55 | jsCtx jsCtx | ||
| 56 | attr attr | ||
| 57 | element element | ||
| 58 | + n parse.Node // for range break/continue | ||
| 59 | err *Error | ||
| 60 | } | ||
| 61 | |||
| 62 | @@ -141,6 +143,8 @@ const ( | ||
| 63 | // stateError is an infectious error state outside any valid | ||
| 64 | // HTML/CSS/JS construct. | ||
| 65 | stateError | ||
| 66 | + // stateDead marks unreachable code after a {{break}} or {{continue}}. | ||
| 67 | + stateDead | ||
| 68 | ) | ||
| 69 | |||
| 70 | // isComment is true for any state that contains content meant for template | ||
| 71 | diff --git a/src/html/template/escape.go b/src/html/template/escape.go | ||
| 72 | index 8739735..6dea79c 100644 | ||
| 73 | --- a/src/html/template/escape.go | ||
| 74 | +++ b/src/html/template/escape.go | ||
| 75 | @@ -97,6 +97,15 @@ type escaper struct { | ||
| 76 | actionNodeEdits map[*parse.ActionNode][]string | ||
| 77 | templateNodeEdits map[*parse.TemplateNode]string | ||
| 78 | textNodeEdits map[*parse.TextNode][]byte | ||
| 79 | + // rangeContext holds context about the current range loop. | ||
| 80 | + rangeContext *rangeContext | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +// rangeContext holds information about the current range loop. | ||
| 84 | +type rangeContext struct { | ||
| 85 | + outer *rangeContext // outer loop | ||
| 86 | + breaks []context // context at each break action | ||
| 87 | + continues []context // context at each continue action | ||
| 88 | } | ||
| 89 | |||
| 90 | // makeEscaper creates a blank escaper for the given set. | ||
| 91 | @@ -109,6 +118,7 @@ func makeEscaper(n *nameSpace) escaper { | ||
| 92 | map[*parse.ActionNode][]string{}, | ||
| 93 | map[*parse.TemplateNode]string{}, | ||
| 94 | map[*parse.TextNode][]byte{}, | ||
| 95 | + nil, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | @@ -124,8 +134,16 @@ func (e *escaper) escape(c context, n parse.Node) context { | ||
| 100 | switch n := n.(type) { | ||
| 101 | case *parse.ActionNode: | ||
| 102 | return e.escapeAction(c, n) | ||
| 103 | + case *parse.BreakNode: | ||
| 104 | + c.n = n | ||
| 105 | + e.rangeContext.breaks = append(e.rangeContext.breaks, c) | ||
| 106 | + return context{state: stateDead} | ||
| 107 | case *parse.CommentNode: | ||
| 108 | return c | ||
| 109 | + case *parse.ContinueNode: | ||
| 110 | + c.n = n | ||
| 111 | + e.rangeContext.continues = append(e.rangeContext.breaks, c) | ||
| 112 | + return context{state: stateDead} | ||
| 113 | case *parse.IfNode: | ||
| 114 | return e.escapeBranch(c, &n.BranchNode, "if") | ||
| 115 | case *parse.ListNode: | ||
| 116 | @@ -427,6 +445,12 @@ func join(a, b context, node parse.Node, nodeName string) context { | ||
| 117 | if b.state == stateError { | ||
| 118 | return b | ||
| 119 | } | ||
| 120 | + if a.state == stateDead { | ||
| 121 | + return b | ||
| 122 | + } | ||
| 123 | + if b.state == stateDead { | ||
| 124 | + return a | ||
| 125 | + } | ||
| 126 | if a.eq(b) { | ||
| 127 | return a | ||
| 128 | } | ||
| 129 | @@ -466,14 +490,27 @@ func join(a, b context, node parse.Node, nodeName string) context { | ||
| 130 | |||
| 131 | // escapeBranch escapes a branch template node: "if", "range" and "with". | ||
| 132 | func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) context { | ||
| 133 | + if nodeName == "range" { | ||
| 134 | + e.rangeContext = &rangeContext{outer: e.rangeContext} | ||
| 135 | + } | ||
| 136 | c0 := e.escapeList(c, n.List) | ||
| 137 | - if nodeName == "range" && c0.state != stateError { | ||
| 138 | + if nodeName == "range" { | ||
| 139 | + if c0.state != stateError { | ||
| 140 | + c0 = joinRange(c0, e.rangeContext) | ||
| 141 | + } | ||
| 142 | + e.rangeContext = e.rangeContext.outer | ||
| 143 | + if c0.state == stateError { | ||
| 144 | + return c0 | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | // The "true" branch of a "range" node can execute multiple times. | ||
| 148 | // We check that executing n.List once results in the same context | ||
| 149 | // as executing n.List twice. | ||
| 150 | + e.rangeContext = &rangeContext{outer: e.rangeContext} | ||
| 151 | c1, _ := e.escapeListConditionally(c0, n.List, nil) | ||
| 152 | c0 = join(c0, c1, n, nodeName) | ||
| 153 | if c0.state == stateError { | ||
| 154 | + e.rangeContext = e.rangeContext.outer | ||
| 155 | // Make clear that this is a problem on loop re-entry | ||
| 156 | // since developers tend to overlook that branch when | ||
| 157 | // debugging templates. | ||
| 158 | @@ -481,11 +518,39 @@ func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) | ||
| 159 | c0.err.Description = "on range loop re-entry: " + c0.err.Description | ||
| 160 | return c0 | ||
| 161 | } | ||
| 162 | + c0 = joinRange(c0, e.rangeContext) | ||
| 163 | + e.rangeContext = e.rangeContext.outer | ||
| 164 | + if c0.state == stateError { | ||
| 165 | + return c0 | ||
| 166 | + } | ||
| 167 | } | ||
| 168 | c1 := e.escapeList(c, n.ElseList) | ||
| 169 | return join(c0, c1, n, nodeName) | ||
| 170 | } | ||
| 171 | |||
| 172 | +func joinRange(c0 context, rc *rangeContext) context { | ||
| 173 | + // Merge contexts at break and continue statements into overall body context. | ||
| 174 | + // In theory we could treat breaks differently from continues, but for now it is | ||
| 175 | + // enough to treat them both as going back to the start of the loop (which may then stop). | ||
| 176 | + for _, c := range rc.breaks { | ||
| 177 | + c0 = join(c0, c, c.n, "range") | ||
| 178 | + if c0.state == stateError { | ||
| 179 | + c0.err.Line = c.n.(*parse.BreakNode).Line | ||
| 180 | + c0.err.Description = "at range loop break: " + c0.err.Description | ||
| 181 | + return c0 | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + for _, c := range rc.continues { | ||
| 185 | + c0 = join(c0, c, c.n, "range") | ||
| 186 | + if c0.state == stateError { | ||
| 187 | + c0.err.Line = c.n.(*parse.ContinueNode).Line | ||
| 188 | + c0.err.Description = "at range loop continue: " + c0.err.Description | ||
| 189 | + return c0 | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + return c0 | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | // escapeList escapes a list template node. | ||
| 196 | func (e *escaper) escapeList(c context, n *parse.ListNode) context { | ||
| 197 | if n == nil { | ||
| 198 | @@ -493,6 +558,9 @@ func (e *escaper) escapeList(c context, n *parse.ListNode) context { | ||
| 199 | } | ||
| 200 | for _, m := range n.Nodes { | ||
| 201 | c = e.escape(c, m) | ||
| 202 | + if c.state == stateDead { | ||
| 203 | + break | ||
| 204 | + } | ||
| 205 | } | ||
| 206 | return c | ||
| 207 | } | ||
| 208 | @@ -503,6 +571,7 @@ func (e *escaper) escapeList(c context, n *parse.ListNode) context { | ||
| 209 | // which is the same as whether e was updated. | ||
| 210 | func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter func(*escaper, context) bool) (context, bool) { | ||
| 211 | e1 := makeEscaper(e.ns) | ||
| 212 | + e1.rangeContext = e.rangeContext | ||
| 213 | // Make type inferences available to f. | ||
| 214 | for k, v := range e.output { | ||
| 215 | e1.output[k] = v | ||
| 216 | diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go | ||
| 217 | index fbc84a7..3b0aa8c 100644 | ||
| 218 | --- a/src/html/template/escape_test.go | ||
| 219 | +++ b/src/html/template/escape_test.go | ||
| 220 | @@ -920,6 +920,22 @@ func TestErrors(t *testing.T) { | ||
| 221 | "<a href='/foo?{{range .Items}}&{{.K}}={{.V}}{{end}}'>", | ||
| 222 | "", | ||
| 223 | }, | ||
| 224 | + { | ||
| 225 | + "{{range .Items}}<a{{if .X}}{{end}}>{{end}}", | ||
| 226 | + "", | ||
| 227 | + }, | ||
| 228 | + { | ||
| 229 | + "{{range .Items}}<a{{if .X}}{{end}}>{{continue}}{{end}}", | ||
| 230 | + "", | ||
| 231 | + }, | ||
| 232 | + { | ||
| 233 | + "{{range .Items}}<a{{if .X}}{{end}}>{{break}}{{end}}", | ||
| 234 | + "", | ||
| 235 | + }, | ||
| 236 | + { | ||
| 237 | + "{{range .Items}}<a{{if .X}}{{end}}>{{if .X}}{{break}}{{end}}{{end}}", | ||
| 238 | + "", | ||
| 239 | + }, | ||
| 240 | // Error cases. | ||
| 241 | { | ||
| 242 | "{{if .Cond}}<a{{end}}", | ||
| 243 | @@ -956,6 +972,14 @@ func TestErrors(t *testing.T) { | ||
| 244 | "z:2:8: on range loop re-entry: {{range}} branches", | ||
| 245 | }, | ||
| 246 | { | ||
| 247 | + "{{range .Items}}<a{{if .X}}{{break}}{{end}}>{{end}}", | ||
| 248 | + "z:1:29: at range loop break: {{range}} branches end in different contexts", | ||
| 249 | + }, | ||
| 250 | + { | ||
| 251 | + "{{range .Items}}<a{{if .X}}{{continue}}{{end}}>{{end}}", | ||
| 252 | + "z:1:29: at range loop continue: {{range}} branches end in different contexts", | ||
| 253 | + }, | ||
| 254 | + { | ||
| 255 | "<a b=1 c={{.H}}", | ||
| 256 | "z: ends in a non-text context: {stateAttr delimSpaceOrTagEnd", | ||
| 257 | }, | ||
| 258 | diff --git a/src/html/template/exec_test.go b/src/html/template/exec_test.go | ||
| 259 | index 8885873..523340b 100644 | ||
| 260 | --- a/src/html/template/exec_test.go | ||
| 261 | +++ b/src/html/template/exec_test.go | ||
| 262 | @@ -567,6 +567,8 @@ var execTests = []execTest{ | ||
| 263 | {"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", tVal, true}, | ||
| 264 | {"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true}, | ||
| 265 | {"range empty else", "{{range .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, | ||
| 266 | + {"range []int break else", "{{range .SI}}-{{.}}-{{break}}NOTREACHED{{else}}EMPTY{{end}}", "-3-", tVal, true}, | ||
| 267 | + {"range []int continue else", "{{range .SI}}-{{.}}-{{continue}}NOTREACHED{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true}, | ||
| 268 | {"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", tVal, true}, | ||
| 269 | {"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", "-20--21--22-", tVal, true}, | ||
| 270 | {"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, true}, | ||
| 271 | diff --git a/src/text/template/doc.go b/src/text/template/doc.go | ||
| 272 | index 7b30294..0228b15 100644 | ||
| 273 | --- a/src/text/template/doc.go | ||
| 274 | +++ b/src/text/template/doc.go | ||
| 275 | @@ -112,6 +112,14 @@ data, defined in detail in the corresponding sections that follow. | ||
| 276 | T0 is executed; otherwise, dot is set to the successive elements | ||
| 277 | of the array, slice, or map and T1 is executed. | ||
| 278 | |||
| 279 | + {{break}} | ||
| 280 | + The innermost {{range pipeline}} loop is ended early, stopping the | ||
| 281 | + current iteration and bypassing all remaining iterations. | ||
| 282 | + | ||
| 283 | + {{continue}} | ||
| 284 | + The current iteration of the innermost {{range pipeline}} loop is | ||
| 285 | + stopped, and the loop starts the next iteration. | ||
| 286 | + | ||
| 287 | {{template "name"}} | ||
| 288 | The template with the specified name is executed with nil data. | ||
| 289 | |||
| 290 | diff --git a/src/text/template/exec.go b/src/text/template/exec.go | ||
| 291 | index 5ad3b4e..92fa9d9 100644 | ||
| 292 | --- a/src/text/template/exec.go | ||
| 293 | +++ b/src/text/template/exec.go | ||
| 294 | @@ -5,6 +5,7 @@ | ||
| 295 | package template | ||
| 296 | |||
| 297 | import ( | ||
| 298 | + "errors" | ||
| 299 | "fmt" | ||
| 300 | "internal/fmtsort" | ||
| 301 | "io" | ||
| 302 | @@ -243,6 +244,12 @@ func (t *Template) DefinedTemplates() string { | ||
| 303 | return b.String() | ||
| 304 | } | ||
| 305 | |||
| 306 | +// Sentinel errors for use with panic to signal early exits from range loops. | ||
| 307 | +var ( | ||
| 308 | + walkBreak = errors.New("break") | ||
| 309 | + walkContinue = errors.New("continue") | ||
| 310 | +) | ||
| 311 | + | ||
| 312 | // Walk functions step through the major pieces of the template structure, | ||
| 313 | // generating output as they go. | ||
| 314 | func (s *state) walk(dot reflect.Value, node parse.Node) { | ||
| 315 | @@ -255,7 +262,11 @@ func (s *state) walk(dot reflect.Value, node parse.Node) { | ||
| 316 | if len(node.Pipe.Decl) == 0 { | ||
| 317 | s.printValue(node, val) | ||
| 318 | } | ||
| 319 | + case *parse.BreakNode: | ||
| 320 | + panic(walkBreak) | ||
| 321 | case *parse.CommentNode: | ||
| 322 | + case *parse.ContinueNode: | ||
| 323 | + panic(walkContinue) | ||
| 324 | case *parse.IfNode: | ||
| 325 | s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList) | ||
| 326 | case *parse.ListNode: | ||
| 327 | @@ -334,6 +345,11 @@ func isTrue(val reflect.Value) (truth, ok bool) { | ||
| 328 | |||
| 329 | func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { | ||
| 330 | s.at(r) | ||
| 331 | + defer func() { | ||
| 332 | + if r := recover(); r != nil && r != walkBreak { | ||
| 333 | + panic(r) | ||
| 334 | + } | ||
| 335 | + }() | ||
| 336 | defer s.pop(s.mark()) | ||
| 337 | val, _ := indirect(s.evalPipeline(dot, r.Pipe)) | ||
| 338 | // mark top of stack before any variables in the body are pushed. | ||
| 339 | @@ -347,8 +363,14 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) { | ||
| 340 | if len(r.Pipe.Decl) > 1 { | ||
| 341 | s.setTopVar(2, index) | ||
| 342 | } | ||
| 343 | + defer s.pop(mark) | ||
| 344 | + defer func() { | ||
| 345 | + // Consume panic(walkContinue) | ||
| 346 | + if r := recover(); r != nil && r != walkContinue { | ||
| 347 | + panic(r) | ||
| 348 | + } | ||
| 349 | + }() | ||
| 350 | s.walk(elem, r.List) | ||
| 351 | - s.pop(mark) | ||
| 352 | } | ||
| 353 | switch val.Kind() { | ||
| 354 | case reflect.Array, reflect.Slice: | ||
| 355 | diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go | ||
| 356 | index ef52164..586af55 100644 | ||
| 357 | --- a/src/text/template/exec_test.go | ||
| 358 | +++ b/src/text/template/exec_test.go | ||
| 359 | @@ -564,6 +564,8 @@ var execTests = []execTest{ | ||
| 360 | {"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", tVal, true}, | ||
| 361 | {"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true}, | ||
| 362 | {"range empty else", "{{range .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, | ||
| 363 | + {"range []int break else", "{{range .SI}}-{{.}}-{{break}}NOTREACHED{{else}}EMPTY{{end}}", "-3-", tVal, true}, | ||
| 364 | + {"range []int continue else", "{{range .SI}}-{{.}}-{{continue}}NOTREACHED{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true}, | ||
| 365 | {"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", tVal, true}, | ||
| 366 | {"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", "-20--21--22-", tVal, true}, | ||
| 367 | {"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, true}, | ||
| 368 | diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go | ||
| 369 | index 6784071..95e3377 100644 | ||
| 370 | --- a/src/text/template/parse/lex.go | ||
| 371 | +++ b/src/text/template/parse/lex.go | ||
| 372 | @@ -62,6 +62,8 @@ const ( | ||
| 373 | // Keywords appear after all the rest. | ||
| 374 | itemKeyword // used only to delimit the keywords | ||
| 375 | itemBlock // block keyword | ||
| 376 | + itemBreak // break keyword | ||
| 377 | + itemContinue // continue keyword | ||
| 378 | itemDot // the cursor, spelled '.' | ||
| 379 | itemDefine // define keyword | ||
| 380 | itemElse // else keyword | ||
| 381 | @@ -76,6 +78,8 @@ const ( | ||
| 382 | var key = map[string]itemType{ | ||
| 383 | ".": itemDot, | ||
| 384 | "block": itemBlock, | ||
| 385 | + "break": itemBreak, | ||
| 386 | + "continue": itemContinue, | ||
| 387 | "define": itemDefine, | ||
| 388 | "else": itemElse, | ||
| 389 | "end": itemEnd, | ||
| 390 | @@ -119,6 +123,8 @@ type lexer struct { | ||
| 391 | parenDepth int // nesting depth of ( ) exprs | ||
| 392 | line int // 1+number of newlines seen | ||
| 393 | startLine int // start line of this item | ||
| 394 | + breakOK bool // break keyword allowed | ||
| 395 | + continueOK bool // continue keyword allowed | ||
| 396 | } | ||
| 397 | |||
| 398 | // next returns the next rune in the input. | ||
| 399 | @@ -461,7 +467,12 @@ Loop: | ||
| 400 | } | ||
| 401 | switch { | ||
| 402 | case key[word] > itemKeyword: | ||
| 403 | - l.emit(key[word]) | ||
| 404 | + item := key[word] | ||
| 405 | + if item == itemBreak && !l.breakOK || item == itemContinue && !l.continueOK { | ||
| 406 | + l.emit(itemIdentifier) | ||
| 407 | + } else { | ||
| 408 | + l.emit(item) | ||
| 409 | + } | ||
| 410 | case word[0] == '.': | ||
| 411 | l.emit(itemField) | ||
| 412 | case word == "true", word == "false": | ||
| 413 | diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go | ||
| 414 | index 6510eed..df6aabf 100644 | ||
| 415 | --- a/src/text/template/parse/lex_test.go | ||
| 416 | +++ b/src/text/template/parse/lex_test.go | ||
| 417 | @@ -35,6 +35,8 @@ var itemName = map[itemType]string{ | ||
| 418 | // keywords | ||
| 419 | itemDot: ".", | ||
| 420 | itemBlock: "block", | ||
| 421 | + itemBreak: "break", | ||
| 422 | + itemContinue: "continue", | ||
| 423 | itemDefine: "define", | ||
| 424 | itemElse: "else", | ||
| 425 | itemIf: "if", | ||
| 426 | diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go | ||
| 427 | index 177482f..4726822 100644 | ||
| 428 | --- a/src/text/template/parse/node.go | ||
| 429 | +++ b/src/text/template/parse/node.go | ||
| 430 | @@ -71,6 +71,8 @@ const ( | ||
| 431 | NodeVariable // A $ variable. | ||
| 432 | NodeWith // A with action. | ||
| 433 | NodeComment // A comment. | ||
| 434 | + NodeBreak // A break action. | ||
| 435 | + NodeContinue // A continue action. | ||
| 436 | ) | ||
| 437 | |||
| 438 | // Nodes. | ||
| 439 | @@ -907,6 +909,40 @@ func (i *IfNode) Copy() Node { | ||
| 440 | return i.tr.newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList()) | ||
| 441 | } | ||
| 442 | |||
| 443 | +// BreakNode represents a {{break}} action. | ||
| 444 | +type BreakNode struct { | ||
| 445 | + tr *Tree | ||
| 446 | + NodeType | ||
| 447 | + Pos | ||
| 448 | + Line int | ||
| 449 | +} | ||
| 450 | + | ||
| 451 | +func (t *Tree) newBreak(pos Pos, line int) *BreakNode { | ||
| 452 | + return &BreakNode{tr: t, NodeType: NodeBreak, Pos: pos, Line: line} | ||
| 453 | +} | ||
| 454 | + | ||
| 455 | +func (b *BreakNode) Copy() Node { return b.tr.newBreak(b.Pos, b.Line) } | ||
| 456 | +func (b *BreakNode) String() string { return "{{break}}" } | ||
| 457 | +func (b *BreakNode) tree() *Tree { return b.tr } | ||
| 458 | +func (b *BreakNode) writeTo(sb *strings.Builder) { sb.WriteString("{{break}}") } | ||
| 459 | + | ||
| 460 | +// ContinueNode represents a {{continue}} action. | ||
| 461 | +type ContinueNode struct { | ||
| 462 | + tr *Tree | ||
| 463 | + NodeType | ||
| 464 | + Pos | ||
| 465 | + Line int | ||
| 466 | +} | ||
| 467 | + | ||
| 468 | +func (t *Tree) newContinue(pos Pos, line int) *ContinueNode { | ||
| 469 | + return &ContinueNode{tr: t, NodeType: NodeContinue, Pos: pos, Line: line} | ||
| 470 | +} | ||
| 471 | + | ||
| 472 | +func (c *ContinueNode) Copy() Node { return c.tr.newContinue(c.Pos, c.Line) } | ||
| 473 | +func (c *ContinueNode) String() string { return "{{continue}}" } | ||
| 474 | +func (c *ContinueNode) tree() *Tree { return c.tr } | ||
| 475 | +func (c *ContinueNode) writeTo(sb *strings.Builder) { sb.WriteString("{{continue}}") } | ||
| 476 | + | ||
| 477 | // RangeNode represents a {{range}} action and its commands. | ||
| 478 | type RangeNode struct { | ||
| 479 | BranchNode | ||
| 480 | diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go | ||
| 481 | index 1a63961..d92bed5 100644 | ||
| 482 | --- a/src/text/template/parse/parse.go | ||
| 483 | +++ b/src/text/template/parse/parse.go | ||
| 484 | @@ -31,6 +31,7 @@ type Tree struct { | ||
| 485 | vars []string // variables defined at the moment. | ||
| 486 | treeSet map[string]*Tree | ||
| 487 | actionLine int // line of left delim starting action | ||
| 488 | + rangeDepth int | ||
| 489 | mode Mode | ||
| 490 | } | ||
| 491 | |||
| 492 | @@ -224,6 +225,8 @@ func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer, treeSet ma | ||
| 493 | t.vars = []string{"$"} | ||
| 494 | t.funcs = funcs | ||
| 495 | t.treeSet = treeSet | ||
| 496 | + lex.breakOK = !t.hasFunction("break") | ||
| 497 | + lex.continueOK = !t.hasFunction("continue") | ||
| 498 | } | ||
| 499 | |||
| 500 | // stopParse terminates parsing. | ||
| 501 | @@ -386,6 +389,10 @@ func (t *Tree) action() (n Node) { | ||
| 502 | switch token := t.nextNonSpace(); token.typ { | ||
| 503 | case itemBlock: | ||
| 504 | return t.blockControl() | ||
| 505 | + case itemBreak: | ||
| 506 | + return t.breakControl(token.pos, token.line) | ||
| 507 | + case itemContinue: | ||
| 508 | + return t.continueControl(token.pos, token.line) | ||
| 509 | case itemElse: | ||
| 510 | return t.elseControl() | ||
| 511 | case itemEnd: | ||
| 512 | @@ -405,6 +412,32 @@ func (t *Tree) action() (n Node) { | ||
| 513 | return t.newAction(token.pos, token.line, t.pipeline("command", itemRightDelim)) | ||
| 514 | } | ||
| 515 | |||
| 516 | +// Break: | ||
| 517 | +// {{break}} | ||
| 518 | +// Break keyword is past. | ||
| 519 | +func (t *Tree) breakControl(pos Pos, line int) Node { | ||
| 520 | + if token := t.next(); token.typ != itemRightDelim { | ||
| 521 | + t.unexpected(token, "in {{break}}") | ||
| 522 | + } | ||
| 523 | + if t.rangeDepth == 0 { | ||
| 524 | + t.errorf("{{break}} outside {{range}}") | ||
| 525 | + } | ||
| 526 | + return t.newBreak(pos, line) | ||
| 527 | +} | ||
| 528 | + | ||
| 529 | +// Continue: | ||
| 530 | +// {{continue}} | ||
| 531 | +// Continue keyword is past. | ||
| 532 | +func (t *Tree) continueControl(pos Pos, line int) Node { | ||
| 533 | + if token := t.next(); token.typ != itemRightDelim { | ||
| 534 | + t.unexpected(token, "in {{continue}}") | ||
| 535 | + } | ||
| 536 | + if t.rangeDepth == 0 { | ||
| 537 | + t.errorf("{{continue}} outside {{range}}") | ||
| 538 | + } | ||
| 539 | + return t.newContinue(pos, line) | ||
| 540 | +} | ||
| 541 | + | ||
| 542 | // Pipeline: | ||
| 543 | // declarations? command ('|' command)* | ||
| 544 | func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) { | ||
| 545 | @@ -480,8 +513,14 @@ func (t *Tree) checkPipeline(pipe *PipeNode, context string) { | ||
| 546 | func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) { | ||
| 547 | defer t.popVars(len(t.vars)) | ||
| 548 | pipe = t.pipeline(context, itemRightDelim) | ||
| 549 | + if context == "range" { | ||
| 550 | + t.rangeDepth++ | ||
| 551 | + } | ||
| 552 | var next Node | ||
| 553 | list, next = t.itemList() | ||
| 554 | + if context == "range" { | ||
| 555 | + t.rangeDepth-- | ||
| 556 | + } | ||
| 557 | switch next.Type() { | ||
| 558 | case nodeEnd: //done | ||
| 559 | case nodeElse: | ||
| 560 | @@ -523,7 +562,8 @@ func (t *Tree) ifControl() Node { | ||
| 561 | // {{range pipeline}} itemList {{else}} itemList {{end}} | ||
| 562 | // Range keyword is past. | ||
| 563 | func (t *Tree) rangeControl() Node { | ||
| 564 | - return t.newRange(t.parseControl(false, "range")) | ||
| 565 | + r := t.newRange(t.parseControl(false, "range")) | ||
| 566 | + return r | ||
| 567 | } | ||
| 568 | |||
| 569 | // With: | ||
| 570 | diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go | ||
| 571 | index 9b1be27..c3679a0 100644 | ||
| 572 | --- a/src/text/template/parse/parse_test.go | ||
| 573 | +++ b/src/text/template/parse/parse_test.go | ||
| 574 | @@ -230,6 +230,10 @@ var parseTests = []parseTest{ | ||
| 575 | `{{range $x := .SI}}{{.}}{{end}}`}, | ||
| 576 | {"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError, | ||
| 577 | `{{range $x, $y := .SI}}{{.}}{{end}}`}, | ||
| 578 | + {"range with break", "{{range .SI}}{{.}}{{break}}{{end}}", noError, | ||
| 579 | + `{{range .SI}}{{.}}{{break}}{{end}}`}, | ||
| 580 | + {"range with continue", "{{range .SI}}{{.}}{{continue}}{{end}}", noError, | ||
| 581 | + `{{range .SI}}{{.}}{{continue}}{{end}}`}, | ||
| 582 | {"constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", noError, | ||
| 583 | `{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`}, | ||
| 584 | {"template", "{{template `x`}}", noError, | ||
| 585 | @@ -279,6 +283,10 @@ var parseTests = []parseTest{ | ||
| 586 | {"adjacent args", "{{printf 3`x`}}", hasError, ""}, | ||
| 587 | {"adjacent args with .", "{{printf `x`.}}", hasError, ""}, | ||
| 588 | {"extra end after if", "{{if .X}}a{{else if .Y}}b{{end}}{{end}}", hasError, ""}, | ||
| 589 | + {"break outside range", "{{range .}}{{end}} {{break}}", hasError, ""}, | ||
| 590 | + {"continue outside range", "{{range .}}{{end}} {{continue}}", hasError, ""}, | ||
| 591 | + {"break in range else", "{{range .}}{{else}}{{break}}{{end}}", hasError, ""}, | ||
| 592 | + {"continue in range else", "{{range .}}{{else}}{{continue}}{{end}}", hasError, ""}, | ||
| 593 | // Other kinds of assignments and operators aren't available yet. | ||
| 594 | {"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"}, | ||
| 595 | {"bug0b", "{{$x += 1}}{{$x}}", hasError, ""}, | ||
| 596 | -- | ||
| 597 | 2.7.4 | ||
diff --git a/meta/recipes-devtools/go/go-1.18/CVE-2023-24538.patch b/meta/recipes-devtools/go/go-1.18/CVE-2023-24538_2.patch index 502486befc..f94f0f55c7 100644 --- a/meta/recipes-devtools/go/go-1.18/CVE-2023-24538.patch +++ b/meta/recipes-devtools/go/go-1.18/CVE-2023-24538_2.patch | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | From 07cc3b8711a8efbb5885f56dd90d854049ad2f7d Mon Sep 17 00:00:00 2001 | 1 | From 07cc3b8711a8efbb5885f56dd90d854049ad2f7d Mon Sep 17 00:00:00 2001 |
| 2 | From: Roland Shoemaker <bracewell@google.com> | 2 | From: Roland Shoemaker <bracewell@google.com> |
| 3 | Date: Mon, 20 Mar 2023 11:01:13 -0700 | 3 | Date: Mon, 20 Mar 2023 11:01:13 -0700 |
| 4 | Subject: [PATCH] html/template: disallow actions in JS template literals | 4 | Subject: [PATCH 2/2] html/template: disallow actions in JS template literals |
| 5 | 5 | ||
| 6 | ECMAScript 6 introduced template literals[0][1] which are delimited with | 6 | ECMAScript 6 introduced template literals[0][1] which are delimited with |
| 7 | backticks. These need to be escaped in a similar fashion to the | 7 | backticks. These need to be escaped in a similar fashion to the |
| @@ -52,12 +52,15 @@ CVE: CVE-2023-24538 | |||
| 52 | Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> | 52 | Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> |
| 53 | --- | 53 | --- |
| 54 | src/html/template/context.go | 2 ++ | 54 | src/html/template/context.go | 2 ++ |
| 55 | src/html/template/error.go | 13 +++++++++++++ | 55 | src/html/template/error.go | 13 ++++++++ |
| 56 | src/html/template/escape.go | 11 +++++++++++ | 56 | src/html/template/escape.go | 11 +++++++ |
| 57 | src/html/template/escape_test.go | 66 ++++++++++++++++++++++----------------- | ||
| 57 | src/html/template/js.go | 2 ++ | 58 | src/html/template/js.go | 2 ++ |
| 58 | src/html/template/jsctx_string.go | 9 +++++++++ | 59 | src/html/template/js_test.go | 2 +- |
| 59 | src/html/template/transition.go | 7 ++++++- | 60 | src/html/template/jsctx_string.go | 9 ++++++ |
| 60 | 6 files changed, 43 insertions(+), 1 deletion(-) | 61 | src/html/template/state_string.go | 37 ++++++++++++++++++++-- |
| 62 | src/html/template/transition.go | 7 ++++- | ||
| 63 | 9 files changed, 116 insertions(+), 33 deletions(-) | ||
| 61 | 64 | ||
| 62 | diff --git a/src/html/template/context.go b/src/html/template/context.go | 65 | diff --git a/src/html/template/context.go b/src/html/template/context.go |
| 63 | index f7d4849..0b65313 100644 | 66 | index f7d4849..0b65313 100644 |
| @@ -125,6 +128,104 @@ index 8739735..ca078f4 100644 | |||
| 125 | case stateJSRegexp: | 128 | case stateJSRegexp: |
| 126 | s = append(s, "_html_template_jsregexpescaper") | 129 | s = append(s, "_html_template_jsregexpescaper") |
| 127 | case stateCSS: | 130 | case stateCSS: |
| 131 | diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go | ||
| 132 | index 3b0aa8c..a695b17 100644 | ||
| 133 | --- a/src/html/template/escape_test.go | ||
| 134 | +++ b/src/html/template/escape_test.go | ||
| 135 | @@ -681,35 +681,31 @@ func TestEscape(t *testing.T) { | ||
| 136 | } | ||
| 137 | |||
| 138 | for _, test := range tests { | ||
| 139 | - tmpl := New(test.name) | ||
| 140 | - tmpl = Must(tmpl.Parse(test.input)) | ||
| 141 | - // Check for bug 6459: Tree field was not set in Parse. | ||
| 142 | - if tmpl.Tree != tmpl.text.Tree { | ||
| 143 | - t.Errorf("%s: tree not set properly", test.name) | ||
| 144 | - continue | ||
| 145 | - } | ||
| 146 | - b := new(bytes.Buffer) | ||
| 147 | - if err := tmpl.Execute(b, data); err != nil { | ||
| 148 | - t.Errorf("%s: template execution failed: %s", test.name, err) | ||
| 149 | - continue | ||
| 150 | - } | ||
| 151 | - if w, g := test.output, b.String(); w != g { | ||
| 152 | - t.Errorf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g) | ||
| 153 | - continue | ||
| 154 | - } | ||
| 155 | - b.Reset() | ||
| 156 | - if err := tmpl.Execute(b, pdata); err != nil { | ||
| 157 | - t.Errorf("%s: template execution failed for pointer: %s", test.name, err) | ||
| 158 | - continue | ||
| 159 | - } | ||
| 160 | - if w, g := test.output, b.String(); w != g { | ||
| 161 | - t.Errorf("%s: escaped output for pointer: want\n\t%q\ngot\n\t%q", test.name, w, g) | ||
| 162 | - continue | ||
| 163 | - } | ||
| 164 | - if tmpl.Tree != tmpl.text.Tree { | ||
| 165 | - t.Errorf("%s: tree mismatch", test.name) | ||
| 166 | - continue | ||
| 167 | - } | ||
| 168 | + t.Run(test.name, func(t *testing.T) { | ||
| 169 | + tmpl := New(test.name) | ||
| 170 | + tmpl = Must(tmpl.Parse(test.input)) | ||
| 171 | + // Check for bug 6459: Tree field was not set in Parse. | ||
| 172 | + if tmpl.Tree != tmpl.text.Tree { | ||
| 173 | + t.Fatalf("%s: tree not set properly", test.name) | ||
| 174 | + } | ||
| 175 | + b := new(strings.Builder) | ||
| 176 | + if err := tmpl.Execute(b, data); err != nil { | ||
| 177 | + t.Fatalf("%s: template execution failed: %s", test.name, err) | ||
| 178 | + } | ||
| 179 | + if w, g := test.output, b.String(); w != g { | ||
| 180 | + t.Fatalf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g) | ||
| 181 | + } | ||
| 182 | + b.Reset() | ||
| 183 | + if err := tmpl.Execute(b, pdata); err != nil { | ||
| 184 | + t.Fatalf("%s: template execution failed for pointer: %s", test.name, err) | ||
| 185 | + } | ||
| 186 | + if w, g := test.output, b.String(); w != g { | ||
| 187 | + t.Fatalf("%s: escaped output for pointer: want\n\t%q\ngot\n\t%q", test.name, w, g) | ||
| 188 | + } | ||
| 189 | + if tmpl.Tree != tmpl.text.Tree { | ||
| 190 | + t.Fatalf("%s: tree mismatch", test.name) | ||
| 191 | + } | ||
| 192 | + }) | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | @@ -936,6 +932,10 @@ func TestErrors(t *testing.T) { | ||
| 197 | "{{range .Items}}<a{{if .X}}{{end}}>{{if .X}}{{break}}{{end}}{{end}}", | ||
| 198 | "", | ||
| 199 | }, | ||
| 200 | + { | ||
| 201 | + "<script>var a = `${a+b}`</script>`", | ||
| 202 | + "", | ||
| 203 | + }, | ||
| 204 | // Error cases. | ||
| 205 | { | ||
| 206 | "{{if .Cond}}<a{{end}}", | ||
| 207 | @@ -1082,6 +1082,10 @@ func TestErrors(t *testing.T) { | ||
| 208 | // html is allowed since it is the last command in the pipeline, but urlquery is not. | ||
| 209 | `predefined escaper "urlquery" disallowed in template`, | ||
| 210 | }, | ||
| 211 | + { | ||
| 212 | + "<script>var tmpl = `asd {{.}}`;</script>", | ||
| 213 | + `{{.}} appears in a JS template literal`, | ||
| 214 | + }, | ||
| 215 | } | ||
| 216 | for _, test := range tests { | ||
| 217 | buf := new(bytes.Buffer) | ||
| 218 | @@ -1304,6 +1308,10 @@ func TestEscapeText(t *testing.T) { | ||
| 219 | context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript}, | ||
| 220 | }, | ||
| 221 | { | ||
| 222 | + "<a onclick=\"`foo", | ||
| 223 | + context{state: stateJSBqStr, delim: delimDoubleQuote, attr: attrScript}, | ||
| 224 | + }, | ||
| 225 | + { | ||
| 226 | `<A ONCLICK="'`, | ||
| 227 | context{state: stateJSSqStr, delim: delimDoubleQuote, attr: attrScript}, | ||
| 228 | }, | ||
| 128 | diff --git a/src/html/template/js.go b/src/html/template/js.go | 229 | diff --git a/src/html/template/js.go b/src/html/template/js.go |
| 129 | index ea9c183..b888eaf 100644 | 230 | index ea9c183..b888eaf 100644 |
| 130 | --- a/src/html/template/js.go | 231 | --- a/src/html/template/js.go |
| @@ -145,6 +246,19 @@ index ea9c183..b888eaf 100644 | |||
| 145 | '+': `\u002b`, | 246 | '+': `\u002b`, |
| 146 | '/': `\/`, | 247 | '/': `\/`, |
| 147 | '<': `\u003c`, | 248 | '<': `\u003c`, |
| 249 | diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go | ||
| 250 | index d7ee47b..7d963ae 100644 | ||
| 251 | --- a/src/html/template/js_test.go | ||
| 252 | +++ b/src/html/template/js_test.go | ||
| 253 | @@ -292,7 +292,7 @@ func TestEscapersOnLower7AndSelectHighCodepoints(t *testing.T) { | ||
| 254 | `0123456789:;\u003c=\u003e?` + | ||
| 255 | `@ABCDEFGHIJKLMNO` + | ||
| 256 | `PQRSTUVWXYZ[\\]^_` + | ||
| 257 | - "`abcdefghijklmno" + | ||
| 258 | + "\\u0060abcdefghijklmno" + | ||
| 259 | "pqrstuvwxyz{|}~\u007f" + | ||
| 260 | "\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E", | ||
| 261 | }, | ||
| 148 | diff --git a/src/html/template/jsctx_string.go b/src/html/template/jsctx_string.go | 262 | diff --git a/src/html/template/jsctx_string.go b/src/html/template/jsctx_string.go |
| 149 | index dd1d87e..2394893 100644 | 263 | index dd1d87e..2394893 100644 |
| 150 | --- a/src/html/template/jsctx_string.go | 264 | --- a/src/html/template/jsctx_string.go |
| @@ -165,6 +279,55 @@ index dd1d87e..2394893 100644 | |||
| 165 | const _jsCtx_name = "jsCtxRegexpjsCtxDivOpjsCtxUnknown" | 279 | const _jsCtx_name = "jsCtxRegexpjsCtxDivOpjsCtxUnknown" |
| 166 | 280 | ||
| 167 | var _jsCtx_index = [...]uint8{0, 11, 21, 33} | 281 | var _jsCtx_index = [...]uint8{0, 11, 21, 33} |
| 282 | diff --git a/src/html/template/state_string.go b/src/html/template/state_string.go | ||
| 283 | index 05104be..6fb1a6e 100644 | ||
| 284 | --- a/src/html/template/state_string.go | ||
| 285 | +++ b/src/html/template/state_string.go | ||
| 286 | @@ -4,9 +4,42 @@ package template | ||
| 287 | |||
| 288 | import "strconv" | ||
| 289 | |||
| 290 | -const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError" | ||
| 291 | +func _() { | ||
| 292 | + // An "invalid array index" compiler error signifies that the constant values have changed. | ||
| 293 | + // Re-run the stringer command to generate them again. | ||
| 294 | + var x [1]struct{} | ||
| 295 | + _ = x[stateText-0] | ||
| 296 | + _ = x[stateTag-1] | ||
| 297 | + _ = x[stateAttrName-2] | ||
| 298 | + _ = x[stateAfterName-3] | ||
| 299 | + _ = x[stateBeforeValue-4] | ||
| 300 | + _ = x[stateHTMLCmt-5] | ||
| 301 | + _ = x[stateRCDATA-6] | ||
| 302 | + _ = x[stateAttr-7] | ||
| 303 | + _ = x[stateURL-8] | ||
| 304 | + _ = x[stateSrcset-9] | ||
| 305 | + _ = x[stateJS-10] | ||
| 306 | + _ = x[stateJSDqStr-11] | ||
| 307 | + _ = x[stateJSSqStr-12] | ||
| 308 | + _ = x[stateJSBqStr-13] | ||
| 309 | + _ = x[stateJSRegexp-14] | ||
| 310 | + _ = x[stateJSBlockCmt-15] | ||
| 311 | + _ = x[stateJSLineCmt-16] | ||
| 312 | + _ = x[stateCSS-17] | ||
| 313 | + _ = x[stateCSSDqStr-18] | ||
| 314 | + _ = x[stateCSSSqStr-19] | ||
| 315 | + _ = x[stateCSSDqURL-20] | ||
| 316 | + _ = x[stateCSSSqURL-21] | ||
| 317 | + _ = x[stateCSSURL-22] | ||
| 318 | + _ = x[stateCSSBlockCmt-23] | ||
| 319 | + _ = x[stateCSSLineCmt-24] | ||
| 320 | + _ = x[stateError-25] | ||
| 321 | + _ = x[stateDead-26] | ||
| 322 | +} | ||
| 323 | + | ||
| 324 | +const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" | ||
| 325 | |||
| 326 | -var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 155, 170, 184, 192, 205, 218, 231, 244, 255, 271, 286, 296} | ||
| 327 | +var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 204, 217, 230, 243, 256, 267, 283, 298, 308, 317} | ||
| 328 | |||
| 329 | func (i state) String() string { | ||
| 330 | if i >= state(len(_state_index)-1) { | ||
| 168 | diff --git a/src/html/template/transition.go b/src/html/template/transition.go | 331 | diff --git a/src/html/template/transition.go b/src/html/template/transition.go |
| 169 | index 06df679..92eb351 100644 | 332 | index 06df679..92eb351 100644 |
| 170 | --- a/src/html/template/transition.go | 333 | --- a/src/html/template/transition.go |
diff --git a/meta/recipes-devtools/go/go-1.21/CVE-2023-39318.patch b/meta/recipes-devtools/go/go-1.21/CVE-2023-39318.patch index 85c6ec97c8..503a4a288a 100644 --- a/meta/recipes-devtools/go/go-1.21/CVE-2023-39318.patch +++ b/meta/recipes-devtools/go/go-1.21/CVE-2023-39318.patch | |||
| @@ -32,11 +32,11 @@ CVE: CVE-2023-39318 | |||
| 32 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> | 32 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> |
| 33 | --- | 33 | --- |
| 34 | src/html/template/context.go | 6 ++- | 34 | src/html/template/context.go | 6 ++- |
| 35 | src/html/template/escape.go | 5 +- | 35 | src/html/template/escape.go | 5 ++- |
| 36 | src/html/template/escape_test.go | 10 ++++ | 36 | src/html/template/escape_test.go | 10 +++++ |
| 37 | src/html/template/state_string.go | 4 +- | 37 | src/html/template/state_string.go | 26 +++++++------ |
| 38 | src/html/template/transition.go | 80 ++++++++++++++++++++----------- | 38 | src/html/template/transition.go | 80 +++++++++++++++++++++++++-------------- |
| 39 | 5 files changed, 72 insertions(+), 33 deletions(-) | 39 | 5 files changed, 84 insertions(+), 43 deletions(-) |
| 40 | 40 | ||
| 41 | diff --git a/src/html/template/context.go b/src/html/template/context.go | 41 | diff --git a/src/html/template/context.go b/src/html/template/context.go |
| 42 | index f5f44a1..feb6517 100644 | 42 | index f5f44a1..feb6517 100644 |
| @@ -105,14 +105,38 @@ diff --git a/src/html/template/state_string.go b/src/html/template/state_string. | |||
| 105 | index 05104be..b5cfe70 100644 | 105 | index 05104be..b5cfe70 100644 |
| 106 | --- a/src/html/template/state_string.go | 106 | --- a/src/html/template/state_string.go |
| 107 | +++ b/src/html/template/state_string.go | 107 | +++ b/src/html/template/state_string.go |
| 108 | @@ -4,9 +4,9 @@ package template | 108 | @@ -25,21 +25,23 @@ func _() { |
| 109 | 109 | _ = x[stateJSRegexp-14] | |
| 110 | import "strconv" | 110 | _ = x[stateJSBlockCmt-15] |
| 111 | _ = x[stateJSLineCmt-16] | ||
| 112 | - _ = x[stateCSS-17] | ||
| 113 | - _ = x[stateCSSDqStr-18] | ||
| 114 | - _ = x[stateCSSSqStr-19] | ||
| 115 | - _ = x[stateCSSDqURL-20] | ||
| 116 | - _ = x[stateCSSSqURL-21] | ||
| 117 | - _ = x[stateCSSURL-22] | ||
| 118 | - _ = x[stateCSSBlockCmt-23] | ||
| 119 | - _ = x[stateCSSLineCmt-24] | ||
| 120 | - _ = x[stateError-25] | ||
| 121 | - _ = x[stateDead-26] | ||
| 122 | + _ = x[stateJSHTMLOpenCmt-17] | ||
| 123 | + _ = x[stateJSHTMLCloseCmt-18] | ||
| 124 | + _ = x[stateCSS-19] | ||
| 125 | + _ = x[stateCSSDqStr-20] | ||
| 126 | + _ = x[stateCSSSqStr-21] | ||
| 127 | + _ = x[stateCSSDqURL-22] | ||
| 128 | + _ = x[stateCSSSqURL-23] | ||
| 129 | + _ = x[stateCSSURL-24] | ||
| 130 | + _ = x[stateCSSBlockCmt-25] | ||
| 131 | + _ = x[stateCSSLineCmt-26] | ||
| 132 | + _ = x[stateError-27] | ||
| 133 | + _ = x[stateDead-28] | ||
| 134 | } | ||
| 111 | 135 | ||
| 112 | -const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateError" | 136 | -const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" |
| 113 | +const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" | 137 | +const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead" |
| 114 | 138 | ||
| 115 | -var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 155, 170, 184, 192, 205, 218, 231, 244, 255, 271, 286, 296} | 139 | -var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 204, 217, 230, 243, 256, 267, 283, 298, 308, 317} |
| 116 | +var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 214, 233, 241, 254, 267, 280, 293, 304, 320, 335, 345, 354} | 140 | +var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 214, 233, 241, 254, 267, 280, 293, 304, 320, 335, 345, 354} |
| 117 | 141 | ||
| 118 | func (i state) String() string { | 142 | func (i state) String() string { |
