diff options
Diffstat (limited to 'meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch')
-rw-r--r-- | meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch | 393 |
1 files changed, 393 insertions, 0 deletions
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 @@ | |||
1 | From 7ddce23c7d5b728acf8482f5006497c7b9915f8a Mon Sep 17 00:00:00 2001 | ||
2 | From: Ariel Mashraki <ariel@mashraki.co.il> | ||
3 | Date: Wed, 22 Apr 2020 22:17:56 +0300 | ||
4 | Subject: [PATCH 3/6] text/template: add CommentNode to template parse tree | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | Fixes #34652 | ||
10 | |||
11 | Change-Id: Icf6e3eda593fed826736f34f95a9d66f5450cc98 | ||
12 | Reviewed-on: https://go-review.googlesource.com/c/go/+/229398 | ||
13 | Reviewed-by: Daniel Martà <mvdan@mvdan.cc> | ||
14 | Run-TryBot: Daniel Martà <mvdan@mvdan.cc> | ||
15 | TryBot-Result: Gobot Gobot <gobot@golang.org> | ||
16 | |||
17 | Dependency Patch #3 | ||
18 | |||
19 | Upstream-Status: Backport from https://github.com/golang/go/commit/c8ea03828b0645b1fd5725888e44873b75fcfbb6 | ||
20 | CVE: CVE-2023-24538 | ||
21 | Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> | ||
22 | --- | ||
23 | api/next.txt | 19 +++++++++++++++++++ | ||
24 | src/html/template/escape.go | 2 ++ | ||
25 | src/html/template/template_test.go | 16 ++++++++++++++++ | ||
26 | src/text/template/exec.go | 1 + | ||
27 | src/text/template/parse/lex.go | 8 +++++++- | ||
28 | src/text/template/parse/lex_test.go | 7 +++++-- | ||
29 | src/text/template/parse/node.go | 33 +++++++++++++++++++++++++++++++++ | ||
30 | src/text/template/parse/parse.go | 22 +++++++++++++++++++--- | ||
31 | src/text/template/parse/parse_test.go | 25 +++++++++++++++++++++++++ | ||
32 | 9 files changed, 127 insertions(+), 6 deletions(-) | ||
33 | |||
34 | diff --git a/api/next.txt b/api/next.txt | ||
35 | index e69de29..076f39e 100644 | ||
36 | --- a/api/next.txt | ||
37 | +++ b/api/next.txt | ||
38 | @@ -0,0 +1,19 @@ | ||
39 | +pkg unicode, const Version = "13.0.0" | ||
40 | +pkg unicode, var Chorasmian *RangeTable | ||
41 | +pkg unicode, var Dives_Akuru *RangeTable | ||
42 | +pkg unicode, var Khitan_Small_Script *RangeTable | ||
43 | +pkg unicode, var Yezidi *RangeTable | ||
44 | +pkg text/template/parse, const NodeComment = 20 | ||
45 | +pkg text/template/parse, const NodeComment NodeType | ||
46 | +pkg text/template/parse, const ParseComments = 1 | ||
47 | +pkg text/template/parse, const ParseComments Mode | ||
48 | +pkg text/template/parse, method (*CommentNode) Copy() Node | ||
49 | +pkg text/template/parse, method (*CommentNode) String() string | ||
50 | +pkg text/template/parse, method (CommentNode) Position() Pos | ||
51 | +pkg text/template/parse, method (CommentNode) Type() NodeType | ||
52 | +pkg text/template/parse, type CommentNode struct | ||
53 | +pkg text/template/parse, type CommentNode struct, Text string | ||
54 | +pkg text/template/parse, type CommentNode struct, embedded NodeType | ||
55 | +pkg text/template/parse, type CommentNode struct, embedded Pos | ||
56 | +pkg text/template/parse, type Mode uint | ||
57 | +pkg text/template/parse, type Tree struct, Mode Mode | ||
58 | diff --git a/src/html/template/escape.go b/src/html/template/escape.go | ||
59 | index f12dafa..8739735 100644 | ||
60 | --- a/src/html/template/escape.go | ||
61 | +++ b/src/html/template/escape.go | ||
62 | @@ -124,6 +124,8 @@ func (e *escaper) escape(c context, n parse.Node) context { | ||
63 | switch n := n.(type) { | ||
64 | case *parse.ActionNode: | ||
65 | return e.escapeAction(c, n) | ||
66 | + case *parse.CommentNode: | ||
67 | + return c | ||
68 | case *parse.IfNode: | ||
69 | return e.escapeBranch(c, &n.BranchNode, "if") | ||
70 | case *parse.ListNode: | ||
71 | diff --git a/src/html/template/template_test.go b/src/html/template/template_test.go | ||
72 | index 86bd4db..1f2c888 100644 | ||
73 | --- a/src/html/template/template_test.go | ||
74 | +++ b/src/html/template/template_test.go | ||
75 | @@ -10,6 +10,7 @@ import ( | ||
76 | . "html/template" | ||
77 | "strings" | ||
78 | "testing" | ||
79 | + "text/template/parse" | ||
80 | ) | ||
81 | |||
82 | func TestTemplateClone(t *testing.T) { | ||
83 | @@ -160,6 +161,21 @@ func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) { | ||
84 | } | ||
85 | } | ||
86 | |||
87 | +func TestSkipEscapeComments(t *testing.T) { | ||
88 | + c := newTestCase(t) | ||
89 | + tr := parse.New("root") | ||
90 | + tr.Mode = parse.ParseComments | ||
91 | + newT, err := tr.Parse("{{/* A comment */}}{{ 1 }}{{/* Another comment */}}", "", "", make(map[string]*parse.Tree)) | ||
92 | + if err != nil { | ||
93 | + t.Fatalf("Cannot parse template text: %v", err) | ||
94 | + } | ||
95 | + c.root, err = c.root.AddParseTree("root", newT) | ||
96 | + if err != nil { | ||
97 | + t.Fatalf("Cannot add parse tree to template: %v", err) | ||
98 | + } | ||
99 | + c.mustExecute(c.root, nil, "1") | ||
100 | +} | ||
101 | + | ||
102 | type testCase struct { | ||
103 | t *testing.T | ||
104 | root *Template | ||
105 | diff --git a/src/text/template/exec.go b/src/text/template/exec.go | ||
106 | index ac3e741..7ac5175 100644 | ||
107 | --- a/src/text/template/exec.go | ||
108 | +++ b/src/text/template/exec.go | ||
109 | @@ -256,6 +256,7 @@ func (s *state) walk(dot reflect.Value, node parse.Node) { | ||
110 | if len(node.Pipe.Decl) == 0 { | ||
111 | s.printValue(node, val) | ||
112 | } | ||
113 | + case *parse.CommentNode: | ||
114 | case *parse.IfNode: | ||
115 | s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList) | ||
116 | case *parse.ListNode: | ||
117 | diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go | ||
118 | index 30371f2..e41373a 100644 | ||
119 | --- a/src/text/template/parse/lex.go | ||
120 | +++ b/src/text/template/parse/lex.go | ||
121 | @@ -41,6 +41,7 @@ const ( | ||
122 | itemBool // boolean constant | ||
123 | itemChar // printable ASCII character; grab bag for comma etc. | ||
124 | itemCharConstant // character constant | ||
125 | + itemComment // comment text | ||
126 | itemComplex // complex constant (1+2i); imaginary is just a number | ||
127 | itemAssign // equals ('=') introducing an assignment | ||
128 | itemDeclare // colon-equals (':=') introducing a declaration | ||
129 | @@ -112,6 +113,7 @@ type lexer struct { | ||
130 | leftDelim string // start of action | ||
131 | rightDelim string // end of action | ||
132 | trimRightDelim string // end of action with trim marker | ||
133 | + emitComment bool // emit itemComment tokens. | ||
134 | pos Pos // current position in the input | ||
135 | start Pos // start position of this item | ||
136 | width Pos // width of last rune read from input | ||
137 | @@ -203,7 +205,7 @@ func (l *lexer) drain() { | ||
138 | } | ||
139 | |||
140 | // lex creates a new scanner for the input string. | ||
141 | -func lex(name, input, left, right string) *lexer { | ||
142 | +func lex(name, input, left, right string, emitComment bool) *lexer { | ||
143 | if left == "" { | ||
144 | left = leftDelim | ||
145 | } | ||
146 | @@ -216,6 +218,7 @@ func lex(name, input, left, right string) *lexer { | ||
147 | leftDelim: left, | ||
148 | rightDelim: right, | ||
149 | trimRightDelim: rightTrimMarker + right, | ||
150 | + emitComment: emitComment, | ||
151 | items: make(chan item), | ||
152 | line: 1, | ||
153 | startLine: 1, | ||
154 | @@ -323,6 +326,9 @@ func lexComment(l *lexer) stateFn { | ||
155 | if !delim { | ||
156 | return l.errorf("comment ends before closing delimiter") | ||
157 | } | ||
158 | + if l.emitComment { | ||
159 | + l.emit(itemComment) | ||
160 | + } | ||
161 | if trimSpace { | ||
162 | l.pos += trimMarkerLen | ||
163 | } | ||
164 | diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go | ||
165 | index 563c4fc..f6d5f28 100644 | ||
166 | --- a/src/text/template/parse/lex_test.go | ||
167 | +++ b/src/text/template/parse/lex_test.go | ||
168 | @@ -15,6 +15,7 @@ var itemName = map[itemType]string{ | ||
169 | itemBool: "bool", | ||
170 | itemChar: "char", | ||
171 | itemCharConstant: "charconst", | ||
172 | + itemComment: "comment", | ||
173 | itemComplex: "complex", | ||
174 | itemDeclare: ":=", | ||
175 | itemEOF: "EOF", | ||
176 | @@ -90,6 +91,7 @@ var lexTests = []lexTest{ | ||
177 | {"text", `now is the time`, []item{mkItem(itemText, "now is the time"), tEOF}}, | ||
178 | {"text with comment", "hello-{{/* this is a comment */}}-world", []item{ | ||
179 | mkItem(itemText, "hello-"), | ||
180 | + mkItem(itemComment, "/* this is a comment */"), | ||
181 | mkItem(itemText, "-world"), | ||
182 | tEOF, | ||
183 | }}, | ||
184 | @@ -311,6 +313,7 @@ var lexTests = []lexTest{ | ||
185 | }}, | ||
186 | {"trimming spaces before and after comment", "hello- {{- /* hello */ -}} -world", []item{ | ||
187 | mkItem(itemText, "hello-"), | ||
188 | + mkItem(itemComment, "/* hello */"), | ||
189 | mkItem(itemText, "-world"), | ||
190 | tEOF, | ||
191 | }}, | ||
192 | @@ -389,7 +392,7 @@ var lexTests = []lexTest{ | ||
193 | |||
194 | // collect gathers the emitted items into a slice. | ||
195 | func collect(t *lexTest, left, right string) (items []item) { | ||
196 | - l := lex(t.name, t.input, left, right) | ||
197 | + l := lex(t.name, t.input, left, right, true) | ||
198 | for { | ||
199 | item := l.nextItem() | ||
200 | items = append(items, item) | ||
201 | @@ -529,7 +532,7 @@ func TestPos(t *testing.T) { | ||
202 | func TestShutdown(t *testing.T) { | ||
203 | // We need to duplicate template.Parse here to hold on to the lexer. | ||
204 | const text = "erroneous{{define}}{{else}}1234" | ||
205 | - lexer := lex("foo", text, "{{", "}}") | ||
206 | + lexer := lex("foo", text, "{{", "}}", false) | ||
207 | _, err := New("root").parseLexer(lexer) | ||
208 | if err == nil { | ||
209 | t.Fatalf("expected error") | ||
210 | diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go | ||
211 | index 1c116ea..a9dad5e 100644 | ||
212 | --- a/src/text/template/parse/node.go | ||
213 | +++ b/src/text/template/parse/node.go | ||
214 | @@ -70,6 +70,7 @@ const ( | ||
215 | NodeTemplate // A template invocation action. | ||
216 | NodeVariable // A $ variable. | ||
217 | NodeWith // A with action. | ||
218 | + NodeComment // A comment. | ||
219 | ) | ||
220 | |||
221 | // Nodes. | ||
222 | @@ -149,6 +150,38 @@ func (t *TextNode) Copy() Node { | ||
223 | return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: append([]byte{}, t.Text...)} | ||
224 | } | ||
225 | |||
226 | +// CommentNode holds a comment. | ||
227 | +type CommentNode struct { | ||
228 | + NodeType | ||
229 | + Pos | ||
230 | + tr *Tree | ||
231 | + Text string // Comment text. | ||
232 | +} | ||
233 | + | ||
234 | +func (t *Tree) newComment(pos Pos, text string) *CommentNode { | ||
235 | + return &CommentNode{tr: t, NodeType: NodeComment, Pos: pos, Text: text} | ||
236 | +} | ||
237 | + | ||
238 | +func (c *CommentNode) String() string { | ||
239 | + var sb strings.Builder | ||
240 | + c.writeTo(&sb) | ||
241 | + return sb.String() | ||
242 | +} | ||
243 | + | ||
244 | +func (c *CommentNode) writeTo(sb *strings.Builder) { | ||
245 | + sb.WriteString("{{") | ||
246 | + sb.WriteString(c.Text) | ||
247 | + sb.WriteString("}}") | ||
248 | +} | ||
249 | + | ||
250 | +func (c *CommentNode) tree() *Tree { | ||
251 | + return c.tr | ||
252 | +} | ||
253 | + | ||
254 | +func (c *CommentNode) Copy() Node { | ||
255 | + return &CommentNode{tr: c.tr, NodeType: NodeComment, Pos: c.Pos, Text: c.Text} | ||
256 | +} | ||
257 | + | ||
258 | // PipeNode holds a pipeline with optional declaration | ||
259 | type PipeNode struct { | ||
260 | NodeType | ||
261 | diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go | ||
262 | index c9b80f4..496d8bf 100644 | ||
263 | --- a/src/text/template/parse/parse.go | ||
264 | +++ b/src/text/template/parse/parse.go | ||
265 | @@ -21,6 +21,7 @@ type Tree struct { | ||
266 | Name string // name of the template represented by the tree. | ||
267 | ParseName string // name of the top-level template during parsing, for error messages. | ||
268 | Root *ListNode // top-level root of the tree. | ||
269 | + Mode Mode // parsing mode. | ||
270 | text string // text parsed to create the template (or its parent) | ||
271 | // Parsing only; cleared after parse. | ||
272 | funcs []map[string]interface{} | ||
273 | @@ -29,8 +30,16 @@ type Tree struct { | ||
274 | peekCount int | ||
275 | vars []string // variables defined at the moment. | ||
276 | treeSet map[string]*Tree | ||
277 | + mode Mode | ||
278 | } | ||
279 | |||
280 | +// A mode value is a set of flags (or 0). Modes control parser behavior. | ||
281 | +type Mode uint | ||
282 | + | ||
283 | +const ( | ||
284 | + ParseComments Mode = 1 << iota // parse comments and add them to AST | ||
285 | +) | ||
286 | + | ||
287 | // Copy returns a copy of the Tree. Any parsing state is discarded. | ||
288 | func (t *Tree) Copy() *Tree { | ||
289 | if t == nil { | ||
290 | @@ -220,7 +229,8 @@ func (t *Tree) stopParse() { | ||
291 | func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) { | ||
292 | defer t.recover(&err) | ||
293 | t.ParseName = t.Name | ||
294 | - t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim), treeSet) | ||
295 | + emitComment := t.Mode&ParseComments != 0 | ||
296 | + t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim, emitComment), treeSet) | ||
297 | t.text = text | ||
298 | t.parse() | ||
299 | t.add() | ||
300 | @@ -240,12 +250,14 @@ func (t *Tree) add() { | ||
301 | } | ||
302 | } | ||
303 | |||
304 | -// IsEmptyTree reports whether this tree (node) is empty of everything but space. | ||
305 | +// IsEmptyTree reports whether this tree (node) is empty of everything but space or comments. | ||
306 | func IsEmptyTree(n Node) bool { | ||
307 | switch n := n.(type) { | ||
308 | case nil: | ||
309 | return true | ||
310 | case *ActionNode: | ||
311 | + case *CommentNode: | ||
312 | + return true | ||
313 | case *IfNode: | ||
314 | case *ListNode: | ||
315 | for _, node := range n.Nodes { | ||
316 | @@ -276,6 +288,7 @@ func (t *Tree) parse() { | ||
317 | if t.nextNonSpace().typ == itemDefine { | ||
318 | newT := New("definition") // name will be updated once we know it. | ||
319 | newT.text = t.text | ||
320 | + newT.Mode = t.Mode | ||
321 | newT.ParseName = t.ParseName | ||
322 | newT.startParse(t.funcs, t.lex, t.treeSet) | ||
323 | newT.parseDefinition() | ||
324 | @@ -331,13 +344,15 @@ func (t *Tree) itemList() (list *ListNode, next Node) { | ||
325 | } | ||
326 | |||
327 | // textOrAction: | ||
328 | -// text | action | ||
329 | +// text | comment | action | ||
330 | func (t *Tree) textOrAction() Node { | ||
331 | switch token := t.nextNonSpace(); token.typ { | ||
332 | case itemText: | ||
333 | return t.newText(token.pos, token.val) | ||
334 | case itemLeftDelim: | ||
335 | return t.action() | ||
336 | + case itemComment: | ||
337 | + return t.newComment(token.pos, token.val) | ||
338 | default: | ||
339 | t.unexpected(token, "input") | ||
340 | } | ||
341 | @@ -539,6 +554,7 @@ func (t *Tree) blockControl() Node { | ||
342 | |||
343 | block := New(name) // name will be updated once we know it. | ||
344 | block.text = t.text | ||
345 | + block.Mode = t.Mode | ||
346 | block.ParseName = t.ParseName | ||
347 | block.startParse(t.funcs, t.lex, t.treeSet) | ||
348 | var end Node | ||
349 | diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go | ||
350 | index 4e09a78..d9c13c5 100644 | ||
351 | --- a/src/text/template/parse/parse_test.go | ||
352 | +++ b/src/text/template/parse/parse_test.go | ||
353 | @@ -348,6 +348,30 @@ func TestParseCopy(t *testing.T) { | ||
354 | testParse(true, t) | ||
355 | } | ||
356 | |||
357 | +func TestParseWithComments(t *testing.T) { | ||
358 | + textFormat = "%q" | ||
359 | + defer func() { textFormat = "%s" }() | ||
360 | + tests := [...]parseTest{ | ||
361 | + {"comment", "{{/*\n\n\n*/}}", noError, "{{/*\n\n\n*/}}"}, | ||
362 | + {"comment trim left", "x \r\n\t{{- /* hi */}}", noError, `"x"{{/* hi */}}`}, | ||
363 | + {"comment trim right", "{{/* hi */ -}}\n\n\ty", noError, `{{/* hi */}}"y"`}, | ||
364 | + {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", noError, `"x"{{/* */}}"y"`}, | ||
365 | + } | ||
366 | + for _, test := range tests { | ||
367 | + t.Run(test.name, func(t *testing.T) { | ||
368 | + tr := New(test.name) | ||
369 | + tr.Mode = ParseComments | ||
370 | + tmpl, err := tr.Parse(test.input, "", "", make(map[string]*Tree)) | ||
371 | + if err != nil { | ||
372 | + t.Errorf("%q: expected error; got none", test.name) | ||
373 | + } | ||
374 | + if result := tmpl.Root.String(); result != test.result { | ||
375 | + t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result) | ||
376 | + } | ||
377 | + }) | ||
378 | + } | ||
379 | +} | ||
380 | + | ||
381 | type isEmptyTest struct { | ||
382 | name string | ||
383 | input string | ||
384 | @@ -358,6 +382,7 @@ var isEmptyTests = []isEmptyTest{ | ||
385 | {"empty", ``, true}, | ||
386 | {"nonempty", `hello`, false}, | ||
387 | {"spaces only", " \t\n \t\n", true}, | ||
388 | + {"comment only", "{{/* comment */}}", true}, | ||
389 | {"definition", `{{define "x"}}something{{end}}`, true}, | ||
390 | {"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true}, | ||
391 | {"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n", false}, | ||
392 | -- | ||
393 | 2.7.4 | ||