Преглед изворни кода

Add specific error for oneof with nil element.

Signed-off-by: David Symonds <dsymonds@golang.org>
Bryan Mills пре 10 година
родитељ
комит
8d92cf5fc1
2 измењених фајлова са 19 додато и 4 уклоњено
  1. 12 3
      proto/all_test.go
  2. 7 1
      proto/encode.go

+ 12 - 3
proto/all_test.go

@@ -1329,9 +1329,18 @@ func TestRequiredFieldEnforcement(t *testing.T) {
 
 func TestTypedNilMarshal(t *testing.T) {
 	// A typed nil should return ErrNil and not crash.
-	_, err := Marshal((*GoEnum)(nil))
-	if err != ErrNil {
-		t.Errorf("Marshal: got err %v, want ErrNil", err)
+	{
+		var m *GoEnum
+		if _, err := Marshal(m); err != ErrNil {
+			t.Errorf("Marshal(%#v): got %v, want ErrNil", m, err)
+		}
+	}
+
+	{
+		m := &Communique{Union: &Communique_Msg{nil}}
+		if _, err := Marshal(m); err == nil || err == ErrNil {
+			t.Errorf("Marshal(%#v): got %v, want errOneofHasNil", m, err)
+		}
 	}
 }
 

+ 7 - 1
proto/encode.go

@@ -64,6 +64,10 @@ var (
 	// a struct with a repeated field containing a nil element.
 	errRepeatedHasNil = errors.New("proto: repeated field has nil element")
 
+	// errOneofHasNil is the error returned if Marshal is called with
+	// a struct with a oneof field containing a nil element.
+	errOneofHasNil = errors.New("proto: oneof field has nil value")
+
 	// ErrNil is the error returned if Marshal is called with nil.
 	ErrNil = errors.New("proto: Marshal called with nil")
 )
@@ -1222,7 +1226,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
 	// Do oneof fields.
 	if prop.oneofMarshaler != nil {
 		m := structPointer_Interface(base, prop.stype).(Message)
-		if err := prop.oneofMarshaler(m, o); err != nil {
+		if err := prop.oneofMarshaler(m, o); err == ErrNil {
+			return errOneofHasNil
+		} else if err != nil {
 			return err
 		}
 	}