Add logic to catch cases of alias abuse.

Backport of caeefd8.
diff --git a/decode.go b/decode.go
index e4e56e2..91679b5 100644
--- a/decode.go
+++ b/decode.go
@@ -229,6 +229,10 @@
 	mapType reflect.Type
 	terrors []string
 	strict  bool
+
+	decodeCount int
+	aliasCount  int
+	aliasDepth  int
 }
 
 var (
@@ -315,6 +319,13 @@
 }
 
 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")
+	}
 	switch n.kind {
 	case documentNode:
 		return d.document(n, out)
@@ -353,7 +364,9 @@
 		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
 }
diff --git a/decode_test.go b/decode_test.go
index 5feaf60..a60c86b 100644
--- a/decode_test.go
+++ b/decode_test.go
@@ -854,6 +854,18 @@
 	{"{{.}}", `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) {