aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/xml/read.go
diff options
context:
space:
mode:
authorRoland Shoemaker <roland@golang.org>2022-03-28 18:41:26 -0700
committerMichael Knyszek <mknyszek@google.com>2022-07-12 15:05:39 +0000
commit08c46ed43d80bbb67cb904944ea3417989be4af3 (patch)
tree2a4e911fcd01ed5c8eacdd6ee3f56ecb3789c01c /src/encoding/xml/read.go
parentc4c1993fd2a5b26fe45c09592af6d3388a3b2e08 (diff)
downloadgo-08c46ed43d80bbb67cb904944ea3417989be4af3.tar.xz
encoding/xml: use iterative Skip, rather than recursive
Prevents exhausting the stack limit in _incredibly_ deeply nested structures. Fixes #53614 Fixes CVE-2022-28131 Change-Id: I47db4595ce10cecc29fbd06afce7b299868599e6 Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1419912 Reviewed-by: Julie Qiu <julieqiu@google.com> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/417062 Run-TryBot: Michael Knyszek <mknyszek@google.com> Reviewed-by: Heschi Kreinick <heschi@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/encoding/xml/read.go')
-rw-r--r--src/encoding/xml/read.go15
1 files changed, 8 insertions, 7 deletions
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index 01613065e3..a6fb665458 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -747,12 +747,12 @@ Loop:
}
// Skip reads tokens until it has consumed the end element
-// matching the most recent start element already consumed.
-// It recurs if it encounters a start element, so it can be used to
-// skip nested structures.
+// matching the most recent start element already consumed,
+// skipping nested structures.
// It returns nil if it finds an end element matching the start
// element; otherwise it returns an error describing the problem.
func (d *Decoder) Skip() error {
+ var depth int64
for {
tok, err := d.Token()
if err != nil {
@@ -760,11 +760,12 @@ func (d *Decoder) Skip() error {
}
switch tok.(type) {
case StartElement:
- if err := d.Skip(); err != nil {
- return err
- }
+ depth++
case EndElement:
- return nil
+ if depth == 0 {
+ return nil
+ }
+ depth--
}
}
}