Skip to content

Commit

Permalink
Add logic to catch cases of alias abuse.
Browse files Browse the repository at this point in the history
  • Loading branch information
niemeyer committed Jul 8, 2019
1 parent a56cad2 commit caeefd8
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
12 changes: 12 additions & 0 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ type decoder struct {

knownFields bool
uniqueKeys bool
decodeCount int
aliasCount int
aliasDepth int
}

var (
Expand Down Expand Up @@ -432,6 +435,13 @@ func (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field ref
}

func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) {
d.decodeCount++
if d.aliasDepth > 0 {
d.aliasCount++
}
if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > 0.99 {
failf("document contains excessive aliasing")
}
if out.Type() == nodeType {
out.Set(reflect.ValueOf(n).Elem())
return true
Expand Down Expand Up @@ -474,7 +484,9 @@ func (d *decoder) alias(n *Node, out reflect.Value) (good bool) {
failf("anchor '%s' value contains itself", n.Value)
}
d.aliases[n] = true
d.aliasDepth++
good = d.unmarshal(n.Alias, out)
d.aliasDepth--
delete(d.aliases, n)
return good
}
Expand Down
12 changes: 12 additions & 0 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,18 @@ var unmarshalErrorTests = []struct {
{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
{
"a: &a [00,00,00,00,00,00,00,00,00]\n" +
"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +
"c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" +
"d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" +
"e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" +
"f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" +
"g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" +
"h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" +
"i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n",
"yaml: document contains excessive aliasing",
},
}

func (s *S) TestUnmarshalErrors(c *C) {
Expand Down

0 comments on commit caeefd8

Please sign in to comment.