]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: error out instead of panicking on nil dereference
authorEmmanuel Odeke <emm.odeke@gmail.com>
Sun, 17 Jul 2016 21:22:15 +0000 (14:22 -0700)
committerRob Pike <r@golang.org>
Fri, 19 Aug 2016 21:54:39 +0000 (21:54 +0000)
Do not panic when we encounter nil interface values which are
invalid values for gob. Previously this wasn't caught yet
we were calling reflect.*.Type() on reflect.Invalid values
thereby causing panic:
  `panic: reflect: call of reflect.Value.Type on zero Value.`
which is a panic not enforced by encoding/gob itself.
We can catch this and send back an error to the caller.

Fixes #16204

Change-Id: Ie646796db297759a74a02eee5267713adbe0c3a0
Reviewed-on: https://go-review.googlesource.com/24989
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Rob Pike <r@golang.org>

src/encoding/gob/encoder.go
src/encoding/gob/encoder_test.go

index d6c8fdd9630c738a0c7edbd76ff0a694601445ab..40ec81b6e69360945661fe52a13a04cb7ffd6455 100644 (file)
@@ -215,6 +215,9 @@ func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
 // guaranteeing that all necessary type information has been transmitted first.
 // Passing a nil pointer to EncodeValue will panic, as they cannot be transmitted by gob.
 func (enc *Encoder) EncodeValue(value reflect.Value) error {
+       if value.Kind() == reflect.Invalid {
+               return errors.New("gob: cannot encode nil value")
+       }
        if value.Kind() == reflect.Ptr && value.IsNil() {
                panic("gob: cannot encode nil pointer of type " + value.Type().String())
        }
index 22090a18a6f0613c9e867f899612924a2a1c2059..9256848b50e3f945c0ab78fa01b39e4cafb93f10 100644 (file)
@@ -830,6 +830,20 @@ func TestPtrToMapOfMap(t *testing.T) {
        }
 }
 
+// Test that untyped nils generate an error, not a panic.
+// See Issue 16204.
+func TestCatchInvalidNilValue(t *testing.T) {
+       encodeErr, panicErr := encodeAndRecover(nil)
+       if panicErr != nil {
+               t.Fatalf("panicErr=%v, should not panic encoding untyped nil", panicErr)
+       }
+       if encodeErr == nil {
+               t.Errorf("got err=nil, want non-nil error when encoding untyped nil value")
+       } else if !strings.Contains(encodeErr.Error(), "nil value") {
+               t.Errorf("expected 'nil value' error; got err=%v", encodeErr)
+       }
+}
+
 // A top-level nil pointer generates a panic with a helpful string-valued message.
 func TestTopLevelNilPointer(t *testing.T) {
        var ip *int