internal/export/idna: fix infinite loop in Go pre-1.10

lookupString returns 0 for incomplete UTF-8 sequences, so to
prevent infinite loops we must specifically check for that case.
However, CL 73730 which fixed this issue in 2017 was lost in the
shuffle that allowed multiple Unicode versions in x/text (CL 83235),
and the fix was never applied to idna9.0.0.go.

This CL fixes that oversight.

Updates golang/go#22184

Change-Id: I3a6ab08b157f4017560020ff259d1afbe49a9e71
Reviewed-on: https://go-review.googlesource.com/c/text/+/361494
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/export/idna/idna9.0.0.go b/internal/export/idna/idna9.0.0.go
index 96424a0..f217b1a 100644
--- a/internal/export/idna/idna9.0.0.go
+++ b/internal/export/idna/idna9.0.0.go
@@ -197,7 +197,7 @@
 	bidirule func(s string) bool
 }
 
-// A Profile defines the configuration of a IDNA mapper.
+// A Profile defines the configuration of an IDNA mapper.
 type Profile struct {
 	options
 }
@@ -426,6 +426,9 @@
 	}
 	for i := 0; i < len(s); {
 		v, sz := trie.lookupString(s[i:])
+		if sz == 0 {
+			return s, runeError(utf8.RuneError)
+		}
 		// Copy bytes not copied so far.
 		switch p.simplify(info(v).category()) {
 		// TODO: handle the NV8 defined in the Unicode idna data set to allow
@@ -448,6 +451,15 @@
 	)
 	for i := 0; i < len(s); {
 		v, sz := trie.lookupString(s[i:])
+		if sz == 0 {
+			b = append(b, s[k:i]...)
+			b = append(b, "\ufffd"...)
+			k = len(s)
+			if err == nil {
+				err = runeError(utf8.RuneError)
+			}
+			break
+		}
 		start := i
 		i += sz
 		// Copy bytes not copied so far.
@@ -580,6 +592,9 @@
 	}
 	for i := 0; i < len(s); {
 		v, sz := trie.lookupString(s[i:])
+		if sz == 0 {
+			return runeError(utf8.RuneError)
+		}
 		if c := p.simplify(info(v).category()); c != valid && c != deviation {
 			return &labelError{s, "V6"}
 		}
diff --git a/internal/export/idna/idna9.0.0_test.go b/internal/export/idna/idna9.0.0_test.go
index 524727b..91a1e90 100644
--- a/internal/export/idna/idna9.0.0_test.go
+++ b/internal/export/idna/idna9.0.0_test.go
@@ -78,6 +78,7 @@
 		{resolve, "\u3002b", "b", ""},
 		{resolve, "..b", "b", ""},
 		{resolve, "b..", "b..", ""},
+		{resolve, "\xed", "", "P1"},
 
 		// Raw punycode
 		{punyA, "", "", ""},