summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_3.patch
blob: cd7dd0957c3e99b9540159fc5e9923d87ea39da1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
From 7ddce23c7d5b728acf8482f5006497c7b9915f8a Mon Sep 17 00:00:00 2001
From: Ariel Mashraki <ariel@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í <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@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 <skulkarni@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