Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.

Commit caeefd8

Browse files
committed
Add logic to catch cases of alias abuse.
1 parent a56cad2 commit caeefd8

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

decode.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ type decoder struct {
309309

310310
knownFields bool
311311
uniqueKeys bool
312+
decodeCount int
313+
aliasCount int
314+
aliasDepth int
312315
}
313316

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

434437
func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) {
438+
d.decodeCount++
439+
if d.aliasDepth > 0 {
440+
d.aliasCount++
441+
}
442+
if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > 0.99 {
443+
failf("document contains excessive aliasing")
444+
}
435445
if out.Type() == nodeType {
436446
out.Set(reflect.ValueOf(n).Elem())
437447
return true
@@ -474,7 +484,9 @@ func (d *decoder) alias(n *Node, out reflect.Value) (good bool) {
474484
failf("anchor '%s' value contains itself", n.Value)
475485
}
476486
d.aliases[n] = true
487+
d.aliasDepth++
477488
good = d.unmarshal(n.Alias, out)
489+
d.aliasDepth--
478490
delete(d.aliases, n)
479491
return good
480492
}

decode_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,18 @@ var unmarshalErrorTests = []struct {
911911
{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
912912
{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
913913
{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
914+
{
915+
"a: &a [00,00,00,00,00,00,00,00,00]\n" +
916+
"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +
917+
"c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" +
918+
"d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" +
919+
"e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" +
920+
"f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" +
921+
"g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" +
922+
"h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" +
923+
"i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n",
924+
"yaml: document contains excessive aliasing",
925+
},
914926
}
915927

916928
func (s *S) TestUnmarshalErrors(c *C) {

0 commit comments

Comments
 (0)