Commit 7dd086e5 authored by Russ Cox's avatar Russ Cox

encoding/gob: do not use MarshalText, UnmarshalText

This seems to be the best of a long list of bad ways to fix this issue.

Fixes #6760.

R=r
CC=golang-dev
https://golang.org/cl/22770044
parent b6c7cc32
...@@ -736,7 +736,8 @@ now treats channel and function fields of structures as if they were unexported, ...@@ -736,7 +736,8 @@ now treats channel and function fields of structures as if they were unexported,
even if they are not. That is, it ignores them completely. Previously they would even if they are not. That is, it ignores them completely. Previously they would
trigger an error, which could cause unexpected compatibility problems if an trigger an error, which could cause unexpected compatibility problems if an
embedded structure added such a field. embedded structure added such a field.
The package also now supports the generic encoding interfaces of the The package also now supports the generic <code>BinaryMarshaler</code> and
<code>BinaryUnmarshaler</code> interfaces of the
<a href="/pkg/encoding/"><code>encoding</code></a> package <a href="/pkg/encoding/"><code>encoding</code></a> package
described above. described above.
</li> </li>
......
...@@ -86,13 +86,13 @@ Functions and channels will not be sent in a gob. Attempting to encode such a va ...@@ -86,13 +86,13 @@ Functions and channels will not be sent in a gob. Attempting to encode such a va
at top the level will fail. A struct field of chan or func type is treated exactly at top the level will fail. A struct field of chan or func type is treated exactly
like an unexported field and is ignored. like an unexported field and is ignored.
Gob can encode a value of any type implementing the GobEncoder, Gob can encode a value of any type implementing the GobEncoder or
encoding.BinaryMarshaler, or encoding.TextMarshaler interfaces by calling the encoding.BinaryMarshaler interfaces by calling the corresponding method,
corresponding method, in that order of preference. in that order of preference.
Gob can decode a value of any type implementing the GobDecoder, Gob can decode a value of any type implementing the GobDecoder or
encoding.BinaryUnmarshaler, or encoding.TextUnmarshaler interfaces by calling encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
the corresponding method, again in that order of preference. again in that order of preference.
Encoding Details Encoding Details
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net"
"strings" "strings"
"testing" "testing"
"time" "time"
...@@ -767,3 +768,17 @@ func TestGobEncodePtrError(t *testing.T) { ...@@ -767,3 +768,17 @@ func TestGobEncodePtrError(t *testing.T) {
t.Fatalf("expected nil, got %v", err2) t.Fatalf("expected nil, got %v", err2)
} }
} }
func TestNetIP(t *testing.T) {
// Encoding of net.IP{1,2,3,4} in Go 1.1.
enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
var ip net.IP
err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
if err != nil {
t.Fatalf("decode: %v", err)
}
if ip.String() != "1.2.3.4" {
t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
}
}
...@@ -88,18 +88,25 @@ func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) { ...@@ -88,18 +88,25 @@ func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) {
ut.externalEnc, ut.encIndir = xGob, indir ut.externalEnc, ut.encIndir = xGob, indir
} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok { } else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
ut.externalEnc, ut.encIndir = xBinary, indir ut.externalEnc, ut.encIndir = xBinary, indir
} else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
ut.externalEnc, ut.encIndir = xText, indir
} }
// NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
// with older encodings for net.IP. See golang.org/issue/6760.
// } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
// ut.externalEnc, ut.encIndir = xText, indir
// }
if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok { if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
ut.externalDec, ut.decIndir = xGob, indir ut.externalDec, ut.decIndir = xGob, indir
} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok { } else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
ut.externalDec, ut.decIndir = xBinary, indir ut.externalDec, ut.decIndir = xBinary, indir
} else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
ut.externalDec, ut.decIndir = xText, indir
} }
// See note above.
// } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
// ut.externalDec, ut.decIndir = xText, indir
// }
userTypeCache[rt] = ut userTypeCache[rt] = ut
return return
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment