internal/export/idna: avoid memory leak in validation codes
These functions have same issues.
* validateRegistration
* validateAndMap
* validateFromPunycode
When string does not hold enough bytes,
lookupString will return 0 for the size.
In this case, we should raise runeError.
This is the way that we can avoid infinite loop.
Fixes: golang/go#22184
Change-Id: I068e4cc9919777468922deed5d7a427996e0ad61
Reviewed-on: https://go-review.googlesource.com/73730
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/export/idna/idna.go b/internal/export/idna/idna.go
index 9feea64..fd8f3bd 100644
--- a/internal/export/idna/idna.go
+++ b/internal/export/idna/idna.go
@@ -405,6 +405,9 @@
}
for i := 0; i < len(s); {
v, sz := trie.lookupString(s[i:])
+ if sz == 0 {
+ return s, bidi, runeError(utf8.RuneError)
+ }
bidi = bidi || info(v).isBidi(s[i:])
// Copy bytes not copied so far.
switch p.simplify(info(v).category()) {
@@ -446,6 +449,15 @@
var combinedInfoBits info
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
+ }
combinedInfoBits |= info(v)
bidi = bidi || info(v).isBidi(s[i:])
start := i
@@ -584,6 +596,9 @@
// loop.
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/idna_test.go b/internal/export/idna/idna_test.go
index fed6e2e..ff878e5 100644
--- a/internal/export/idna/idna_test.go
+++ b/internal/export/idna/idna_test.go
@@ -167,6 +167,7 @@
{resolve, "\u3002b", ".b", ""},
{resolve, "..b", "..b", ""},
{resolve, "b..", "b..", ""},
+ {resolve, "\xed", "", "P1"},
// Raw punycode
{punyA, "", "", ""},