encoding/asn1: don't parse invalid UTF-8.

Invalid UTF-8 triggers an error when marshaling but, previously, not
when unmarshaling. This means that ASN.1 structures were not
round-tripping.

This change makes invalid UTF-8 in a string marked as UTF-8 to be an
error when Unmarshaling.

Fixes #11126.

Change-Id: Ic37be84d21dc5c03983525e244d955a8b1e1ff14
Reviewed-on: https://go-review.googlesource.com/11056
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Adam Langley 2015-06-13 13:50:02 -07:00 committed by Russ Cox
parent fdd921c9f4
commit 0a6df4a87b
2 changed files with 22 additions and 0 deletions

View File

@ -26,6 +26,7 @@ import (
"reflect"
"strconv"
"time"
"unicode/utf8"
)
// A StructuralError suggests that the ASN.1 data is valid, but the Go type
@ -389,6 +390,9 @@ func parseT61String(bytes []byte) (ret string, err error) {
// parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
// array and returns it.
func parseUTF8String(bytes []byte) (ret string, err error) {
if !utf8.Valid(bytes) {
return "", errors.New("asn1: invalid UTF-8 string")
}
return string(bytes), nil
}

View File

@ -9,6 +9,7 @@ import (
"fmt"
"math/big"
"reflect"
"strings"
"testing"
"time"
)
@ -922,3 +923,20 @@ func TestTruncatedExplicitTag(t *testing.T) {
t.Error("Unmarshal returned without error")
}
}
type invalidUTF8Test struct {
Str string `asn1:"utf8"`
}
func TestUnmarshalInvalidUTF8(t *testing.T) {
data := []byte("0\x05\f\x03a\xc9c")
var result invalidUTF8Test
_, err := Unmarshal(data, &result)
const expectedSubstring = "UTF"
if err == nil {
t.Fatal("Successfully unmarshaled invalid UTF-8 data")
} else if !strings.Contains(err.Error(), expectedSubstring) {
t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
}
}