On Wed, Dec 21, 2022 at 6:32 AM vkumbhar <[email protected]> wrote:
>
> From: Vivek Kumbhar <[email protected]>
>
> Signed-off-by: Vivek Kumbhar <[email protected]>
> ---
>  meta/recipes-devtools/go/go-1.14.inc          |   1 +
>  .../go/go-1.14/CVE-2022-1962.patch            | 421 ++++++++++++++++++
>  2 files changed, 422 insertions(+)
>  create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2022-1962.patch
>
> diff --git a/meta/recipes-devtools/go/go-1.14.inc 
> b/meta/recipes-devtools/go/go-1.14.inc
> index cec37c1b09..0361bc763b 100644
> --- a/meta/recipes-devtools/go/go-1.14.inc
> +++ b/meta/recipes-devtools/go/go-1.14.inc
> @@ -49,6 +49,7 @@ SRC_URI += "\
>      file://CVE-2022-24921.patch \
>      file://CVE-2022-28131.patch \
>      file://CVE-2022-28327.patch \
> +    file://CVE-2022-1962.patch \

This patch will not apply, perhaps a conflict with "golang:
CVE-2022-41715 regexp/syntax: limit memory used by parsing regexps"
which is in the latest pull request?

ERROR: go-native-1.14.15-r0 do_patch: Applying patch
'CVE-2022-1962.patch' on target directory
'/home/steve/builds/poky-contrib/build/tmp/work/x86_64-linux/go-native/1.14.15-r0/go'
Command Error: 'quilt --quiltrc
/home/steve/builds/poky-contrib/build/tmp/work/x86_64-linux/go-native/1.14.15-r0/recipe-sysroot-native/etc/quiltrc
push' exited with 0  Output:
Applying patch CVE-2022-1962.patch
patching file src/go/parser/interface.go
Hunk #1 succeeded at 92 (offset -5 lines).
Hunk #2 succeeded at 191 (offset -15 lines).
patching file src/go/parser/parser.go
Hunk #1 FAILED at 60.
Hunk #2 succeeded at 236 (offset 126 lines).
Hunk #3 succeeded at 366 with fuzz 1 (offset 126 lines).
Hunk #4 succeeded at 1052 with fuzz 2 (offset -89 lines).
Hunk #5 FAILED at 1555.
Hunk #6 FAILED at 1615.
Hunk #7 FAILED at 1697.
Hunk #8 succeeded at 1923 (offset -63 lines).
Hunk #9 succeeded at 2240 (offset -51 lines).
4 out of 9 hunks FAILED -- rejects in file src/go/parser/parser.go
patching file src/go/parser/parser_test.go
Hunk #1 FAILED at 10.
Hunk #2 succeeded at 569 (offset -8 lines).
1 out of 2 hunks FAILED -- rejects in file src/go/parser/parser_test.go
can't find file to patch at input line 375
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/src/go/parser/resolver.go b/src/go/parser/resolver.go
|index cf92c7e4f5..f55bdb7f17 100644
|--- a/src/go/parser/resolver.go
|+++ b/src/go/parser/resolver.go
--------------------------
No file to patch.  Skipping patch.
5 out of 5 hunks ignored
Patch CVE-2022-1962.patch does not apply (enforce with -f)

Steve

>  "
>
>  SRC_URI_append_libc-musl = " 
> file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
> diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2022-1962.patch 
> b/meta/recipes-devtools/go/go-1.14/CVE-2022-1962.patch
> new file mode 100644
> index 0000000000..ceabc9057a
> --- /dev/null
> +++ b/meta/recipes-devtools/go/go-1.14/CVE-2022-1962.patch
> @@ -0,0 +1,421 @@
> +From ba8788ebcead55e99e631c6a1157ad7b35535d11 Mon Sep 17 00:00:00 2001
> +From: Roland Shoemaker <[email protected]>
> +Date: Wed, 15 Jun 2022 10:43:05 -0700
> +Subject: [PATCH] [release-branch.go1.17] go/parser: limit recursion depth
> +
> +Limit nested parsing to 100,000, which prevents stack exhaustion when
> +parsing deeply nested statements, types, and expressions. Also limit
> +the scope depth to 1,000 during object resolution.
> +
> +Thanks to Juho Nurminen of Mattermost for reporting this issue.
> +
> +Fixes #53707
> +Updates #53616
> +Fixes CVE-2022-1962
> +
> +Change-Id: I4d7b86c1d75d0bf3c7af1fdea91582aa74272c64
> +Reviewed-on: 
> https://team-review.git.corp.google.com/c/golang/go-private/+/1491025
> +Reviewed-by: Russ Cox <[email protected]>
> +Reviewed-by: Damien Neil <[email protected]>
> +(cherry picked from commit 6a856f08d58e4b6705c0c337d461c540c1235c83)
> +Reviewed-on: https://go-review.googlesource.com/c/go/+/417070
> +Reviewed-by: Heschi Kreinick <[email protected]>
> +TryBot-Result: Gopher Robot <[email protected]>
> +Run-TryBot: Michael Knyszek <[email protected]>
> +
> +Upstream-Status: Backport 
> [https://github.com/golang/go/commit/ba8788ebcead55e99e631c6a1157ad7b35535d11]
> +CVE: CVE-2022-1962
> +Signed-off-by: Vivek Kumbhar <[email protected]>
> +---
> + src/go/parser/interface.go   |  10 ++-
> + src/go/parser/parser.go      |  54 ++++++++++-
> + src/go/parser/parser_test.go | 169 +++++++++++++++++++++++++++++++++++
> + src/go/parser/resolver.go    |   9 ++
> + 4 files changed, 236 insertions(+), 6 deletions(-)
> +
> +diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go
> +index 85486d2f4b..eae429e6ef 100644
> +--- a/src/go/parser/interface.go
> ++++ b/src/go/parser/interface.go
> +@@ -97,8 +97,11 @@ func ParseFile(fset *token.FileSet, filename string, src 
> interface{}, mode Mode)
> +       defer func() {
> +               if e := recover(); e != nil {
> +                       // resume same panic if it's not a bailout
> +-                      if _, ok := e.(bailout); !ok {
> ++                      bail, ok := e.(bailout)
> ++                      if !ok {
> +                               panic(e)
> ++                      } else if bail.msg != "" {
> ++                              p.errors.Add(p.file.Position(bail.pos), 
> bail.msg)
> +                       }
> +               }
> +
> +@@ -203,8 +206,11 @@ func ParseExprFrom(fset *token.FileSet, filename 
> string, src interface{}, mode M
> +       defer func() {
> +               if e := recover(); e != nil {
> +                       // resume same panic if it's not a bailout
> +-                      if _, ok := e.(bailout); !ok {
> ++                      bail, ok := e.(bailout)
> ++                      if !ok {
> +                               panic(e)
> ++                      } else if bail.msg != "" {
> ++                              p.errors.Add(p.file.Position(bail.pos), 
> bail.msg)
> +                       }
> +               }
> +               p.errors.Sort()
> +diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
> +index f10c8650af..2c42b9f8cc 100644
> +--- a/src/go/parser/parser.go
> ++++ b/src/go/parser/parser.go
> +@@ -60,6 +60,10 @@ type parser struct {
> +       inRhs   bool // if set, the parser is parsing a rhs expression
> +
> +       imports []*ast.ImportSpec // list of imports
> ++
> ++      // nestLev is used to track and limit the recursion depth
> ++      // during parsing.
> ++      nestLev int
> + }
> +
> + func (p *parser) init(fset *token.FileSet, filename string, src []byte, 
> mode Mode) {
> +@@ -110,6 +114,24 @@ func un(p *parser) {
> +       p.printTrace(")")
> + }
> +
> ++// maxNestLev is the deepest we're willing to recurse during parsing
> ++const maxNestLev int = 1e5
> ++
> ++func incNestLev(p *parser) *parser {
> ++      p.nestLev++
> ++      if p.nestLev > maxNestLev {
> ++              p.error(p.pos, "exceeded max nesting depth")
> ++              panic(bailout{})
> ++      }
> ++      return p
> ++}
> ++
> ++// decNestLev is used to track nesting depth during parsing to prevent 
> stack exhaustion.
> ++// It is used along with incNestLev in a similar fashion to how un and 
> trace are used.
> ++func decNestLev(p *parser) {
> ++      p.nestLev--
> ++}
> ++
> + // Advance to the next token.
> + func (p *parser) next0() {
> +       // Because of one-token look-ahead, print the previous token
> +@@ -222,8 +244,12 @@ func (p *parser) next() {
> +       }
> + }
> +
> +-// A bailout panic is raised to indicate early termination.
> +-type bailout struct{}
> ++// A bailout panic is raised to indicate early termination. pos and msg are
> ++// only populated when bailing out of object resolution.
> ++type bailout struct {
> ++      pos token.Pos
> ++      msg string
> ++}
> +
> + func (p *parser) error(pos token.Pos, msg string) {
> +       if p.trace {
> +@@ -1119,6 +1145,8 @@ func (p *parser) parseTypeInstance(typ ast.Expr) 
> ast.Expr {
> + }
> +
> + func (p *parser) tryIdentOrType() ast.Expr {
> ++      defer decNestLev(incNestLev(p))
> ++
> +       switch p.tok {
> +       case token.IDENT:
> +               typ := p.parseTypeName(nil)
> +@@ -1531,7 +1559,13 @@ func (p *parser) parsePrimaryExpr() (x ast.Expr) {
> +       }
> +
> +       x = p.parseOperand()
> +-      for {
> ++      // We track the nesting here rather than at the entry for the 
> function,
> ++      // since it can iteratively produce a nested output, and we want to
> ++      // limit how deep a structure we generate.
> ++      var n int
> ++      defer func() { p.nestLev -= n }()
> ++      for n = 1; ; n++ {
> ++              incNestLev(p)
> +               switch p.tok {
> +               case token.PERIOD:
> +                       p.next()
> +@@ -1591,6 +1625,8 @@ func (p *parser) parsePrimaryExpr() (x ast.Expr) {
> + }
> +
> + func (p *parser) parseUnaryExpr() ast.Expr {
> ++      defer decNestLev(incNestLev(p))
> ++
> +       if p.trace {
> +               defer un(trace(p, "UnaryExpr"))
> +       }
> +@@ -1673,7 +1709,13 @@ func (p *parser) parseBinaryExpr(prec1 int) ast.Expr {
> +       }
> +
> +       x := p.parseUnaryExpr()
> +-      for {
> ++      // We track the nesting here rather than at the entry for the 
> function,
> ++      // since it can iteratively produce a nested output, and we want to
> ++      // limit how deep a structure we generate.
> ++      var n int
> ++      defer func() { p.nestLev -= n }()
> ++      for n = 1; ; n++ {
> ++              incNestLev(p)
> +               op, oprec := p.tokPrec()
> +               if oprec < prec1 {
> +                       return x
> +@@ -1962,6 +2004,8 @@ func (p *parser) parseIfHeader() (init ast.Stmt, cond 
> ast.Expr) {
> + }
> +
> + func (p *parser) parseIfStmt() *ast.IfStmt {
> ++      defer decNestLev(incNestLev(p))
> ++
> +       if p.trace {
> +               defer un(trace(p, "IfStmt"))
> +       }
> +@@ -2265,6 +2309,8 @@ func (p *parser) parseForStmt() ast.Stmt {
> + }
> +
> + func (p *parser) parseStmt() (s ast.Stmt) {
> ++      defer decNestLev(incNestLev(p))
> ++
> +       if p.trace {
> +               defer un(trace(p, "Statement"))
> +       }
> +diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go
> +index a4f882d368..1a46c87866 100644
> +--- a/src/go/parser/parser_test.go
> ++++ b/src/go/parser/parser_test.go
> +@@ -10,6 +10,7 @@ import (
> +       "go/ast"
> +       "go/token"
> +       "io/fs"
> ++      "runtime"
> +       "strings"
> +       "testing"
> + )
> +@@ -577,3 +578,171 @@ type x int // comment
> +               t.Errorf("got %q, want %q", comment, "// comment")
> +       }
> + }
> ++
> ++var parseDepthTests = []struct {
> ++      name   string
> ++      format string
> ++      // multipler is used when a single statement may result in more than 
> one
> ++      // change in the depth level, for instance "1+(..." produces a 
> BinaryExpr
> ++      // followed by a UnaryExpr, which increments the depth twice. The test
> ++      // case comment explains which nodes are triggering the multiple depth
> ++      // changes.
> ++      parseMultiplier int
> ++      // scope is true if we should also test the statement for the 
> resolver scope
> ++      // depth limit.
> ++      scope bool
> ++      // scopeMultiplier does the same as parseMultiplier, but for the scope
> ++      // depths.
> ++      scopeMultiplier int
> ++}{
> ++      // The format expands the part inside « » many times.
> ++      // A second set of brackets nested inside the first stops the 
> repetition,
> ++      // so that for example «(«1»)» expands to (((...((((1))))...))).
> ++      {name: "array", format: "package main; var x «[1]»int"},
> ++      {name: "slice", format: "package main; var x «[]»int"},
> ++      {name: "struct", format: "package main; var x «struct { X «int» }»", 
> scope: true},
> ++      {name: "pointer", format: "package main; var x «*»int"},
> ++      {name: "func", format: "package main; var x «func()»int", scope: 
> true},
> ++      {name: "chan", format: "package main; var x «chan »int"},
> ++      {name: "chan2", format: "package main; var x «<-chan »int"},
> ++      {name: "interface", format: "package main; var x «interface { M() 
> «int» }»", scope: true, scopeMultiplier: 2}, // Scopes: InterfaceType, 
> FuncType
> ++      {name: "map", format: "package main; var x «map[int]»int"},
> ++      {name: "slicelit", format: "package main; var x = «[]any{«»}»", 
> parseMultiplier: 2},             // Parser nodes: UnaryExpr, CompositeLit
> ++      {name: "arraylit", format: "package main; var x = «[1]any{«nil»}»", 
> parseMultiplier: 2},         // Parser nodes: UnaryExpr, CompositeLit
> ++      {name: "structlit", format: "package main; var x = «struct{x 
> any}{«nil»}»", parseMultiplier: 2}, // Parser nodes: UnaryExpr, CompositeLit
> ++      {name: "maplit", format: "package main; var x = 
> «map[int]any{1:«nil»}»", parseMultiplier: 2},    // Parser nodes: 
> CompositeLit, KeyValueExpr
> ++      {name: "dot", format: "package main; var x = «x.»x"},
> ++      {name: "index", format: "package main; var x = x«[1]»"},
> ++      {name: "slice", format: "package main; var x = x«[1:2]»"},
> ++      {name: "slice3", format: "package main; var x = x«[1:2:3]»"},
> ++      {name: "dottype", format: "package main; var x = x«.(any)»"},
> ++      {name: "callseq", format: "package main; var x = x«()»"},
> ++      {name: "methseq", format: "package main; var x = x«.m()»", 
> parseMultiplier: 2}, // Parser nodes: SelectorExpr, CallExpr
> ++      {name: "binary", format: "package main; var x = «1+»1"},
> ++      {name: "binaryparen", format: "package main; var x = «1+(«1»)»", 
> parseMultiplier: 2}, // Parser nodes: BinaryExpr, ParenExpr
> ++      {name: "unary", format: "package main; var x = «^»1"},
> ++      {name: "addr", format: "package main; var x = «& »x"},
> ++      {name: "star", format: "package main; var x = «*»x"},
> ++      {name: "recv", format: "package main; var x = «<-»x"},
> ++      {name: "call", format: "package main; var x = «f(«1»)»", 
> parseMultiplier: 2},    // Parser nodes: Ident, CallExpr
> ++      {name: "conv", format: "package main; var x = «(*T)(«1»)»", 
> parseMultiplier: 2}, // Parser nodes: ParenExpr, CallExpr
> ++      {name: "label", format: "package main; func main() { «Label:» }"},
> ++      {name: "if", format: "package main; func main() { «if true { «» }»}", 
> parseMultiplier: 2, scope: true, scopeMultiplier: 2}, // Parser nodes: 
> IfStmt, BlockStmt. Scopes: IfStmt, BlockStmt
> ++      {name: "ifelse", format: "package main; func main() { «if true {} 
> else » {} }", scope: true},
> ++      {name: "switch", format: "package main; func main() { «switch { 
> default: «» }»}", scope: true, scopeMultiplier: 2},               // Scopes: 
> TypeSwitchStmt, CaseClause
> ++      {name: "typeswitch", format: "package main; func main() { «switch 
> x.(type) { default: «» }» }", scope: true, scopeMultiplier: 2}, // Scopes: 
> TypeSwitchStmt, CaseClause
> ++      {name: "for0", format: "package main; func main() { «for { «» }» }", 
> scope: true, scopeMultiplier: 2},                            // Scopes: 
> ForStmt, BlockStmt
> ++      {name: "for1", format: "package main; func main() { «for x { «» }» 
> }", scope: true, scopeMultiplier: 2},                          // Scopes: 
> ForStmt, BlockStmt
> ++      {name: "for3", format: "package main; func main() { «for f(); g(); 
> h() { «» }» }", scope: true, scopeMultiplier: 2},              // Scopes: 
> ForStmt, BlockStmt
> ++      {name: "forrange0", format: "package main; func main() { «for range x 
> { «» }» }", scope: true, scopeMultiplier: 2},               // Scopes: 
> RangeStmt, BlockStmt
> ++      {name: "forrange1", format: "package main; func main() { «for x = 
> range z { «» }» }", scope: true, scopeMultiplier: 2},           // Scopes: 
> RangeStmt, BlockStmt
> ++      {name: "forrange2", format: "package main; func main() { «for x, y = 
> range z { «» }» }", scope: true, scopeMultiplier: 2},        // Scopes: 
> RangeStmt, BlockStmt
> ++      {name: "go", format: "package main; func main() { «go func() { «» 
> }()» }", parseMultiplier: 2, scope: true},                      // Parser 
> nodes: GoStmt, FuncLit
> ++      {name: "defer", format: "package main; func main() { «defer func() { 
> «» }()» }", parseMultiplier: 2, scope: true},                // Parser nodes: 
> DeferStmt, FuncLit
> ++      {name: "select", format: "package main; func main() { «select { 
> default: «» }» }", scope: true},
> ++}
> ++
> ++// split splits pre«mid»post into pre, mid, post.
> ++// If the string does not have that form, split returns x, "", "".
> ++func split(x string) (pre, mid, post string) {
> ++      start, end := strings.Index(x, "«"), strings.LastIndex(x, "»")
> ++      if start < 0 || end < 0 {
> ++              return x, "", ""
> ++      }
> ++      return x[:start], x[start+len("«") : end], x[end+len("»"):]
> ++}
> ++
> ++func TestParseDepthLimit(t *testing.T) {
> ++      if runtime.GOARCH == "wasm" {
> ++              t.Skip("causes call stack exhaustion on js/wasm")
> ++      }
> ++      for _, tt := range parseDepthTests {
> ++              for _, size := range []string{"small", "big"} {
> ++                      t.Run(tt.name+"/"+size, func(t *testing.T) {
> ++                              n := maxNestLev + 1
> ++                              if tt.parseMultiplier > 0 {
> ++                                      n /= tt.parseMultiplier
> ++                              }
> ++                              if size == "small" {
> ++                                      // Decrease the number of statements 
> by 10, in order to check
> ++                                      // that we do not fail when under the 
> limit. 10 is used to
> ++                                      // provide some wiggle room for cases 
> where the surrounding
> ++                                      // scaffolding syntax adds some noise 
> to the depth that changes
> ++                                      // on a per testcase basis.
> ++                                      n -= 10
> ++                              }
> ++
> ++                              pre, mid, post := split(tt.format)
> ++                              if strings.Contains(mid, "«") {
> ++                                      left, base, right := split(mid)
> ++                                      mid = strings.Repeat(left, n) + base 
> + strings.Repeat(right, n)
> ++                              } else {
> ++                                      mid = strings.Repeat(mid, n)
> ++                              }
> ++                              input := pre + mid + post
> ++
> ++                              fset := token.NewFileSet()
> ++                              _, err := ParseFile(fset, "", input, 
> ParseComments|SkipObjectResolution)
> ++                              if size == "small" {
> ++                                      if err != nil {
> ++                                              t.Errorf("ParseFile(...): %v 
> (want success)", err)
> ++                                      }
> ++                              } else {
> ++                                      expected := "exceeded max nesting 
> depth"
> ++                                      if err == nil || 
> !strings.HasSuffix(err.Error(), expected) {
> ++                                              t.Errorf("ParseFile(...) = _, 
> %v, want %q", err, expected)
> ++                                      }
> ++                              }
> ++                      })
> ++              }
> ++      }
> ++}
> ++
> ++func TestScopeDepthLimit(t *testing.T) {
> ++      if runtime.GOARCH == "wasm" {
> ++              t.Skip("causes call stack exhaustion on js/wasm")
> ++      }
> ++      for _, tt := range parseDepthTests {
> ++              if !tt.scope {
> ++                      continue
> ++              }
> ++              for _, size := range []string{"small", "big"} {
> ++                      t.Run(tt.name+"/"+size, func(t *testing.T) {
> ++                              n := maxScopeDepth + 1
> ++                              if tt.scopeMultiplier > 0 {
> ++                                      n /= tt.scopeMultiplier
> ++                              }
> ++                              if size == "small" {
> ++                                      // Decrease the number of statements 
> by 10, in order to check
> ++                                      // that we do not fail when under the 
> limit. 10 is used to
> ++                                      // provide some wiggle room for cases 
> where the surrounding
> ++                                      // scaffolding syntax adds some noise 
> to the depth that changes
> ++                                      // on a per testcase basis.
> ++                                      n -= 10
> ++                              }
> ++
> ++                              pre, mid, post := split(tt.format)
> ++                              if strings.Contains(mid, "«") {
> ++                                      left, base, right := split(mid)
> ++                                      mid = strings.Repeat(left, n) + base 
> + strings.Repeat(right, n)
> ++                              } else {
> ++                                      mid = strings.Repeat(mid, n)
> ++                              }
> ++                              input := pre + mid + post
> ++
> ++                              fset := token.NewFileSet()
> ++                              _, err := ParseFile(fset, "", input, 
> DeclarationErrors)
> ++                              if size == "small" {
> ++                                      if err != nil {
> ++                                              t.Errorf("ParseFile(...): %v 
> (want success)", err)
> ++                                      }
> ++                              } else {
> ++                                      expected := "exceeded max scope depth 
> during object resolution"
> ++                                      if err == nil || 
> !strings.HasSuffix(err.Error(), expected) {
> ++                                              t.Errorf("ParseFile(...) = _, 
> %v, want %q", err, expected)
> ++                                      }
> ++                              }
> ++                      })
> ++              }
> ++      }
> ++}
> +diff --git a/src/go/parser/resolver.go b/src/go/parser/resolver.go
> +index cf92c7e4f5..f55bdb7f17 100644
> +--- a/src/go/parser/resolver.go
> ++++ b/src/go/parser/resolver.go
> +@@ -25,6 +25,7 @@ func resolveFile(file *ast.File, handle *token.File, 
> declErr func(token.Pos, str
> +               declErr:  declErr,
> +               topScope: pkgScope,
> +               pkgScope: pkgScope,
> ++              depth:    1,
> +       }
> +
> +       for _, decl := range file.Decls {
> +@@ -53,6 +54,8 @@ func resolveFile(file *ast.File, handle *token.File, 
> declErr func(token.Pos, str
> +       file.Unresolved = r.unresolved[0:i]
> + }
> +
> ++const maxScopeDepth int = 1e3
> ++
> + type resolver struct {
> +       handle  *token.File
> +       declErr func(token.Pos, string)
> +@@ -61,6 +64,7 @@ type resolver struct {
> +       pkgScope   *ast.Scope   // pkgScope.Outer == nil
> +       topScope   *ast.Scope   // top-most scope; may be pkgScope
> +       unresolved []*ast.Ident // unresolved identifiers
> ++      depth      int          // scope depth
> +
> +       // Label scopes
> +       // (maintained by open/close LabelScope)
> +@@ -83,6 +87,10 @@ func (r *resolver) sprintf(format string, args 
> ...interface{}) string {
> + }
> +
> + func (r *resolver) openScope(pos token.Pos) {
> ++      r.depth++
> ++      if r.depth > maxScopeDepth {
> ++              panic(bailout{pos: pos, msg: "exceeded max scope depth during 
> object resolution"})
> ++      }
> +       if debugResolve {
> +               r.dump("opening scope @%v", pos)
> +       }
> +@@ -90,6 +98,7 @@ func (r *resolver) openScope(pos token.Pos) {
> + }
> +
> + func (r *resolver) closeScope() {
> ++      r.depth--
> +       if debugResolve {
> +               r.dump("closing scope")
> +       }
> +--
> +2.30.2
> +
> --
> 2.30.2
>
>
> 
>
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#174965): 
https://lists.openembedded.org/g/openembedded-core/message/174965
Mute This Topic: https://lists.openembedded.org/mt/95809427/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to