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

Commit bb4e33b

Browse files
committed
Add logic to catch cases of alias abuse.
Backport of caeefd8.
1 parent 7b8349a commit bb4e33b

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

decode.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ type decoder struct {
229229
mapType reflect.Type
230230
terrors []string
231231
strict bool
232+
233+
decodeCount int
234+
aliasCount int
235+
aliasDepth int
232236
}
233237

234238
var (
@@ -315,6 +319,13 @@ func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unm
315319
}
316320

317321
func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
322+
d.decodeCount++
323+
if d.aliasDepth > 0 {
324+
d.aliasCount++
325+
}
326+
if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > 0.99 {
327+
failf("document contains excessive aliasing")
328+
}
318329
switch n.kind {
319330
case documentNode:
320331
return d.document(n, out)
@@ -353,7 +364,9 @@ func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
353364
failf("anchor '%s' value contains itself", n.value)
354365
}
355366
d.aliases[n] = true
367+
d.aliasDepth++
356368
good = d.unmarshal(n.alias, out)
369+
d.aliasDepth--
357370
delete(d.aliases, n)
358371
return good
359372
}

decode_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,18 @@ var unmarshalErrorTests = []struct {
854854
{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
855855
{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
856856
{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
857+
{
858+
"a: &a [00,00,00,00,00,00,00,00,00]\n" +
859+
"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +
860+
"c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" +
861+
"d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" +
862+
"e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" +
863+
"f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" +
864+
"g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" +
865+
"h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" +
866+
"i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n",
867+
"yaml: document contains excessive aliasing",
868+
},
857869
}
858870

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

0 commit comments

Comments
 (0)