summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch')
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24538_4.patch497
1 files changed, 497 insertions, 0 deletions
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 @@
1From 760d88497091fb5d6d231a18e6f4e06ecb9af9b2 Mon Sep 17 00:00:00 2001
2From: Russ Cox <rsc@golang.org>
3Date: Thu, 10 Sep 2020 18:53:26 -0400
4Subject: [PATCH 4/6] text/template: allow newlines inside action delimiters
5
6This allows multiline constructs like:
7
8 {{"hello" |
9 printf}}
10
11Now that unclosed actions can span multiple lines,
12track and report the start of the action when reporting errors.
13
14Also clean up a few "unexpected <error message>" to be just "<error message>".
15
16Fixes #29770.
17
18Change-Id: I54c6c016029a8328b7902a4b6d85eab713ec3285
19Reviewed-on: https://go-review.googlesource.com/c/go/+/254257
20Trust: Russ Cox <rsc@golang.org>
21Run-TryBot: Russ Cox <rsc@golang.org>
22TryBot-Result: Go Bot <gobot@golang.org>
23Reviewed-by: Rob Pike <r@golang.org>
24
25Dependency Patch #4
26
27Upstream-Status: Backport from https://github.com/golang/go/commit/9384d34c58099657bb1b133beaf3ff37ada9b017
28CVE: CVE-2023-24538
29Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
30---
31 src/text/template/doc.go | 21 ++++-----
32 src/text/template/exec_test.go | 2 +-
33 src/text/template/parse/lex.go | 84 +++++++++++++++++------------------
34 src/text/template/parse/lex_test.go | 2 +-
35 src/text/template/parse/parse.go | 59 +++++++++++++-----------
36 src/text/template/parse/parse_test.go | 36 ++++++++++++---
37 6 files changed, 117 insertions(+), 87 deletions(-)
38
39diff --git a/src/text/template/doc.go b/src/text/template/doc.go
40index 4b0efd2..7b30294 100644
41--- a/src/text/template/doc.go
42+++ b/src/text/template/doc.go
43@@ -40,16 +40,17 @@ More intricate examples appear below.
44 Text and spaces
45
46 By default, all text between actions is copied verbatim when the template is
47-executed. For example, the string " items are made of " in the example above appears
48-on standard output when the program is run.
49-
50-However, to aid in formatting template source code, if an action's left delimiter
51-(by default "{{") is followed immediately by a minus sign and ASCII space character
52-("{{- "), all trailing white space is trimmed from the immediately preceding text.
53-Similarly, if the right delimiter ("}}") is preceded by a space and minus sign
54-(" -}}"), all leading white space is trimmed from the immediately following text.
55-In these trim markers, the ASCII space must be present; "{{-3}}" parses as an
56-action containing the number -3.
57+executed. For example, the string " items are made of " in the example above
58+appears on standard output when the program is run.
59+
60+However, to aid in formatting template source code, if an action's left
61+delimiter (by default "{{") is followed immediately by a minus sign and white
62+space, all trailing white space is trimmed from the immediately preceding text.
63+Similarly, if the right delimiter ("}}") is preceded by white space and a minus
64+sign, all leading white space is trimmed from the immediately following text.
65+In these trim markers, the white space must be present:
66+"{{- 3}}" is like "{{3}}" but trims the immediately preceding text, while
67+"{{-3}}" parses as an action containing the number -3.
68
69 For instance, when executing the template whose source is
70
71diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
72index b8a809e..3309b33 100644
73--- a/src/text/template/exec_test.go
74+++ b/src/text/template/exec_test.go
75@@ -1295,7 +1295,7 @@ func TestUnterminatedStringError(t *testing.T) {
76 t.Fatal("expected error")
77 }
78 str := err.Error()
79- if !strings.Contains(str, "X:3: unexpected unterminated raw quoted string") {
80+ if !strings.Contains(str, "X:3: unterminated raw quoted string") {
81 t.Fatalf("unexpected error: %s", str)
82 }
83 }
84diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
85index e41373a..6784071 100644
86--- a/src/text/template/parse/lex.go
87+++ b/src/text/template/parse/lex.go
88@@ -92,15 +92,14 @@ const eof = -1
89 // If the action begins "{{- " rather than "{{", then all space/tab/newlines
90 // preceding the action are trimmed; conversely if it ends " -}}" the
91 // leading spaces are trimmed. This is done entirely in the lexer; the
92-// parser never sees it happen. We require an ASCII space to be
93-// present to avoid ambiguity with things like "{{-3}}". It reads
94+// parser never sees it happen. We require an ASCII space (' ', \t, \r, \n)
95+// to be present to avoid ambiguity with things like "{{-3}}". It reads
96 // better with the space present anyway. For simplicity, only ASCII
97-// space does the job.
98+// does the job.
99 const (
100- spaceChars = " \t\r\n" // These are the space characters defined by Go itself.
101- leftTrimMarker = "- " // Attached to left delimiter, trims trailing spaces from preceding text.
102- rightTrimMarker = " -" // Attached to right delimiter, trims leading spaces from following text.
103- trimMarkerLen = Pos(len(leftTrimMarker))
104+ spaceChars = " \t\r\n" // These are the space characters defined by Go itself.
105+ trimMarker = '-' // Attached to left/right delimiter, trims trailing spaces from preceding/following text.
106+ trimMarkerLen = Pos(1 + 1) // marker plus space before or after
107 )
108
109 // stateFn represents the state of the scanner as a function that returns the next state.
110@@ -108,19 +107,18 @@ type stateFn func(*lexer) stateFn
111
112 // lexer holds the state of the scanner.
113 type lexer struct {
114- name string // the name of the input; used only for error reports
115- input string // the string being scanned
116- leftDelim string // start of action
117- rightDelim string // end of action
118- trimRightDelim string // end of action with trim marker
119- emitComment bool // emit itemComment tokens.
120- pos Pos // current position in the input
121- start Pos // start position of this item
122- width Pos // width of last rune read from input
123- items chan item // channel of scanned items
124- parenDepth int // nesting depth of ( ) exprs
125- line int // 1+number of newlines seen
126- startLine int // start line of this item
127+ name string // the name of the input; used only for error reports
128+ input string // the string being scanned
129+ leftDelim string // start of action
130+ rightDelim string // end of action
131+ emitComment bool // emit itemComment tokens.
132+ pos Pos // current position in the input
133+ start Pos // start position of this item
134+ width Pos // width of last rune read from input
135+ items chan item // channel of scanned items
136+ parenDepth int // nesting depth of ( ) exprs
137+ line int // 1+number of newlines seen
138+ startLine int // start line of this item
139 }
140
141 // next returns the next rune in the input.
142@@ -213,15 +211,14 @@ func lex(name, input, left, right string, emitComment bool) *lexer {
143 right = rightDelim
144 }
145 l := &lexer{
146- name: name,
147- input: input,
148- leftDelim: left,
149- rightDelim: right,
150- trimRightDelim: rightTrimMarker + right,
151- emitComment: emitComment,
152- items: make(chan item),
153- line: 1,
154- startLine: 1,
155+ name: name,
156+ input: input,
157+ leftDelim: left,
158+ rightDelim: right,
159+ emitComment: emitComment,
160+ items: make(chan item),
161+ line: 1,
162+ startLine: 1,
163 }
164 go l.run()
165 return l
166@@ -251,7 +248,7 @@ func lexText(l *lexer) stateFn {
167 ldn := Pos(len(l.leftDelim))
168 l.pos += Pos(x)
169 trimLength := Pos(0)
170- if strings.HasPrefix(l.input[l.pos+ldn:], leftTrimMarker) {
171+ if hasLeftTrimMarker(l.input[l.pos+ldn:]) {
172 trimLength = rightTrimLength(l.input[l.start:l.pos])
173 }
174 l.pos -= trimLength
175@@ -280,7 +277,7 @@ func rightTrimLength(s string) Pos {
176
177 // atRightDelim reports whether the lexer is at a right delimiter, possibly preceded by a trim marker.
178 func (l *lexer) atRightDelim() (delim, trimSpaces bool) {
179- if strings.HasPrefix(l.input[l.pos:], l.trimRightDelim) { // With trim marker.
180+ if hasRightTrimMarker(l.input[l.pos:]) && strings.HasPrefix(l.input[l.pos+trimMarkerLen:], l.rightDelim) { // With trim marker.
181 return true, true
182 }
183 if strings.HasPrefix(l.input[l.pos:], l.rightDelim) { // Without trim marker.
184@@ -297,7 +294,7 @@ func leftTrimLength(s string) Pos {
185 // lexLeftDelim scans the left delimiter, which is known to be present, possibly with a trim marker.
186 func lexLeftDelim(l *lexer) stateFn {
187 l.pos += Pos(len(l.leftDelim))
188- trimSpace := strings.HasPrefix(l.input[l.pos:], leftTrimMarker)
189+ trimSpace := hasLeftTrimMarker(l.input[l.pos:])
190 afterMarker := Pos(0)
191 if trimSpace {
192 afterMarker = trimMarkerLen
193@@ -342,7 +339,7 @@ func lexComment(l *lexer) stateFn {
194
195 // lexRightDelim scans the right delimiter, which is known to be present, possibly with a trim marker.
196 func lexRightDelim(l *lexer) stateFn {
197- trimSpace := strings.HasPrefix(l.input[l.pos:], rightTrimMarker)
198+ trimSpace := hasRightTrimMarker(l.input[l.pos:])
199 if trimSpace {
200 l.pos += trimMarkerLen
201 l.ignore()
202@@ -369,7 +366,7 @@ func lexInsideAction(l *lexer) stateFn {
203 return l.errorf("unclosed left paren")
204 }
205 switch r := l.next(); {
206- case r == eof || isEndOfLine(r):
207+ case r == eof:
208 return l.errorf("unclosed action")
209 case isSpace(r):
210 l.backup() // Put space back in case we have " -}}".
211@@ -439,7 +436,7 @@ func lexSpace(l *lexer) stateFn {
212 }
213 // Be careful about a trim-marked closing delimiter, which has a minus
214 // after a space. We know there is a space, so check for the '-' that might follow.
215- if strings.HasPrefix(l.input[l.pos-1:], l.trimRightDelim) {
216+ if hasRightTrimMarker(l.input[l.pos-1:]) && strings.HasPrefix(l.input[l.pos-1+trimMarkerLen:], l.rightDelim) {
217 l.backup() // Before the space.
218 if numSpaces == 1 {
219 return lexRightDelim // On the delim, so go right to that.
220@@ -526,7 +523,7 @@ func lexFieldOrVariable(l *lexer, typ itemType) stateFn {
221 // day to implement arithmetic.
222 func (l *lexer) atTerminator() bool {
223 r := l.peek()
224- if isSpace(r) || isEndOfLine(r) {
225+ if isSpace(r) {
226 return true
227 }
228 switch r {
229@@ -657,15 +654,18 @@ Loop:
230
231 // isSpace reports whether r is a space character.
232 func isSpace(r rune) bool {
233- return r == ' ' || r == '\t'
234-}
235-
236-// isEndOfLine reports whether r is an end-of-line character.
237-func isEndOfLine(r rune) bool {
238- return r == '\r' || r == '\n'
239+ return r == ' ' || r == '\t' || r == '\r' || r == '\n'
240 }
241
242 // isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
243 func isAlphaNumeric(r rune) bool {
244 return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
245 }
246+
247+func hasLeftTrimMarker(s string) bool {
248+ return len(s) >= 2 && s[0] == trimMarker && isSpace(rune(s[1]))
249+}
250+
251+func hasRightTrimMarker(s string) bool {
252+ return len(s) >= 2 && isSpace(rune(s[0])) && s[1] == trimMarker
253+}
254diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
255index f6d5f28..6510eed 100644
256--- a/src/text/template/parse/lex_test.go
257+++ b/src/text/template/parse/lex_test.go
258@@ -323,7 +323,7 @@ var lexTests = []lexTest{
259 tLeft,
260 mkItem(itemError, "unrecognized character in action: U+0001"),
261 }},
262- {"unclosed action", "{{\n}}", []item{
263+ {"unclosed action", "{{", []item{
264 tLeft,
265 mkItem(itemError, "unclosed action"),
266 }},
267diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
268index 496d8bf..5e6e512 100644
269--- a/src/text/template/parse/parse.go
270+++ b/src/text/template/parse/parse.go
271@@ -24,13 +24,14 @@ type Tree struct {
272 Mode Mode // parsing mode.
273 text string // text parsed to create the template (or its parent)
274 // Parsing only; cleared after parse.
275- funcs []map[string]interface{}
276- lex *lexer
277- token [3]item // three-token lookahead for parser.
278- peekCount int
279- vars []string // variables defined at the moment.
280- treeSet map[string]*Tree
281- mode Mode
282+ funcs []map[string]interface{}
283+ lex *lexer
284+ token [3]item // three-token lookahead for parser.
285+ peekCount int
286+ vars []string // variables defined at the moment.
287+ treeSet map[string]*Tree
288+ actionLine int // line of left delim starting action
289+ mode Mode
290 }
291
292 // A mode value is a set of flags (or 0). Modes control parser behavior.
293@@ -187,6 +188,16 @@ func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item {
294
295 // unexpected complains about the token and terminates processing.
296 func (t *Tree) unexpected(token item, context string) {
297+ if token.typ == itemError {
298+ extra := ""
299+ if t.actionLine != 0 && t.actionLine != token.line {
300+ extra = fmt.Sprintf(" in action started at %s:%d", t.ParseName, t.actionLine)
301+ if strings.HasSuffix(token.val, " action") {
302+ extra = extra[len(" in action"):] // avoid "action in action"
303+ }
304+ }
305+ t.errorf("%s%s", token, extra)
306+ }
307 t.errorf("unexpected %s in %s", token, context)
308 }
309
310@@ -350,6 +361,8 @@ func (t *Tree) textOrAction() Node {
311 case itemText:
312 return t.newText(token.pos, token.val)
313 case itemLeftDelim:
314+ t.actionLine = token.line
315+ defer t.clearActionLine()
316 return t.action()
317 case itemComment:
318 return t.newComment(token.pos, token.val)
319@@ -359,6 +372,10 @@ func (t *Tree) textOrAction() Node {
320 return nil
321 }
322
323+func (t *Tree) clearActionLine() {
324+ t.actionLine = 0
325+}
326+
327 // Action:
328 // control
329 // command ("|" command)*
330@@ -384,12 +401,12 @@ func (t *Tree) action() (n Node) {
331 t.backup()
332 token := t.peek()
333 // Do not pop variables; they persist until "end".
334- return t.newAction(token.pos, token.line, t.pipeline("command"))
335+ return t.newAction(token.pos, token.line, t.pipeline("command", itemRightDelim))
336 }
337
338 // Pipeline:
339 // declarations? command ('|' command)*
340-func (t *Tree) pipeline(context string) (pipe *PipeNode) {
341+func (t *Tree) pipeline(context string, end itemType) (pipe *PipeNode) {
342 token := t.peekNonSpace()
343 pipe = t.newPipeline(token.pos, token.line, nil)
344 // Are there declarations or assignments?
345@@ -430,12 +447,9 @@ decls:
346 }
347 for {
348 switch token := t.nextNonSpace(); token.typ {
349- case itemRightDelim, itemRightParen:
350+ case end:
351 // At this point, the pipeline is complete
352 t.checkPipeline(pipe, context)
353- if token.typ == itemRightParen {
354- t.backup()
355- }
356 return
357 case itemBool, itemCharConstant, itemComplex, itemDot, itemField, itemIdentifier,
358 itemNumber, itemNil, itemRawString, itemString, itemVariable, itemLeftParen:
359@@ -464,7 +478,7 @@ func (t *Tree) checkPipeline(pipe *PipeNode, context string) {
360
361 func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) {
362 defer t.popVars(len(t.vars))
363- pipe = t.pipeline(context)
364+ pipe = t.pipeline(context, itemRightDelim)
365 var next Node
366 list, next = t.itemList()
367 switch next.Type() {
368@@ -550,7 +564,7 @@ func (t *Tree) blockControl() Node {
369
370 token := t.nextNonSpace()
371 name := t.parseTemplateName(token, context)
372- pipe := t.pipeline(context)
373+ pipe := t.pipeline(context, itemRightDelim)
374
375 block := New(name) // name will be updated once we know it.
376 block.text = t.text
377@@ -580,7 +594,7 @@ func (t *Tree) templateControl() Node {
378 if t.nextNonSpace().typ != itemRightDelim {
379 t.backup()
380 // Do not pop variables; they persist until "end".
381- pipe = t.pipeline(context)
382+ pipe = t.pipeline(context, itemRightDelim)
383 }
384 return t.newTemplate(token.pos, token.line, name, pipe)
385 }
386@@ -614,13 +628,12 @@ func (t *Tree) command() *CommandNode {
387 switch token := t.next(); token.typ {
388 case itemSpace:
389 continue
390- case itemError:
391- t.errorf("%s", token.val)
392 case itemRightDelim, itemRightParen:
393 t.backup()
394 case itemPipe:
395+ // nothing here; break loop below
396 default:
397- t.errorf("unexpected %s in operand", token)
398+ t.unexpected(token, "operand")
399 }
400 break
401 }
402@@ -675,8 +688,6 @@ func (t *Tree) operand() Node {
403 // A nil return means the next item is not a term.
404 func (t *Tree) term() Node {
405 switch token := t.nextNonSpace(); token.typ {
406- case itemError:
407- t.errorf("%s", token.val)
408 case itemIdentifier:
409 if !t.hasFunction(token.val) {
410 t.errorf("function %q not defined", token.val)
411@@ -699,11 +710,7 @@ func (t *Tree) term() Node {
412 }
413 return number
414 case itemLeftParen:
415- pipe := t.pipeline("parenthesized pipeline")
416- if token := t.next(); token.typ != itemRightParen {
417- t.errorf("unclosed right paren: unexpected %s", token)
418- }
419- return pipe
420+ return t.pipeline("parenthesized pipeline", itemRightParen)
421 case itemString, itemRawString:
422 s, err := strconv.Unquote(token.val)
423 if err != nil {
424diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
425index d9c13c5..220f984 100644
426--- a/src/text/template/parse/parse_test.go
427+++ b/src/text/template/parse/parse_test.go
428@@ -250,6 +250,13 @@ var parseTests = []parseTest{
429 {"comment trim left and right", "x \r\n\t{{- /* */ -}}\n\n\ty", noError, `"x""y"`},
430 {"block definition", `{{block "foo" .}}hello{{end}}`, noError,
431 `{{template "foo" .}}`},
432+
433+ {"newline in assignment", "{{ $x \n := \n 1 \n }}", noError, "{{$x := 1}}"},
434+ {"newline in empty action", "{{\n}}", hasError, "{{\n}}"},
435+ {"newline in pipeline", "{{\n\"x\"\n|\nprintf\n}}", noError, `{{"x" | printf}}`},
436+ {"newline in comment", "{{/*\nhello\n*/}}", noError, ""},
437+ {"newline in comment", "{{-\n/*\nhello\n*/\n-}}", noError, ""},
438+
439 // Errors.
440 {"unclosed action", "hello{{range", hasError, ""},
441 {"unmatched end", "{{end}}", hasError, ""},
442@@ -426,23 +433,38 @@ var errorTests = []parseTest{
443 // Check line numbers are accurate.
444 {"unclosed1",
445 "line1\n{{",
446- hasError, `unclosed1:2: unexpected unclosed action in command`},
447+ hasError, `unclosed1:2: unclosed action`},
448 {"unclosed2",
449 "line1\n{{define `x`}}line2\n{{",
450- hasError, `unclosed2:3: unexpected unclosed action in command`},
451+ hasError, `unclosed2:3: unclosed action`},
452+ {"unclosed3",
453+ "line1\n{{\"x\"\n\"y\"\n",
454+ hasError, `unclosed3:4: unclosed action started at unclosed3:2`},
455+ {"unclosed4",
456+ "{{\n\n\n\n\n",
457+ hasError, `unclosed4:6: unclosed action started at unclosed4:1`},
458+ {"var1",
459+ "line1\n{{\nx\n}}",
460+ hasError, `var1:3: function "x" not defined`},
461 // Specific errors.
462 {"function",
463 "{{foo}}",
464 hasError, `function "foo" not defined`},
465- {"comment",
466+ {"comment1",
467 "{{/*}}",
468- hasError, `unclosed comment`},
469+ hasError, `comment1:1: unclosed comment`},
470+ {"comment2",
471+ "{{/*\nhello\n}}",
472+ hasError, `comment2:1: unclosed comment`},
473 {"lparen",
474 "{{.X (1 2 3}}",
475 hasError, `unclosed left paren`},
476 {"rparen",
477- "{{.X 1 2 3)}}",
478- hasError, `unexpected ")"`},
479+ "{{.X 1 2 3 ) }}",
480+ hasError, `unexpected ")" in command`},
481+ {"rparen2",
482+ "{{(.X 1 2 3",
483+ hasError, `unclosed action`},
484 {"space",
485 "{{`x`3}}",
486 hasError, `in operand`},
487@@ -488,7 +510,7 @@ var errorTests = []parseTest{
488 hasError, `missing value for parenthesized pipeline`},
489 {"multilinerawstring",
490 "{{ $v := `\n` }} {{",
491- hasError, `multilinerawstring:2: unexpected unclosed action`},
492+ hasError, `multilinerawstring:2: unclosed action`},
493 {"rangeundefvar",
494 "{{range $k}}{{end}}",
495 hasError, `undefined variable`},
496--
4972.7.4