goprotobuf: Handle nils in repeated message fields in text formatting.
Previously this code would panic. A nil in a repeated message field is,
strictly speaking, invalid, but text formatting is often used for debugging,
and it's much more useful to generate "<nil>" than to panic.
LGTM=r
R=r
CC=golang-codereviews
https://codereview.appspot.com/87960043
diff --git a/proto/text.go b/proto/text.go
index b4a5dbb..5063009 100644
--- a/proto/text.go
+++ b/proto/text.go
@@ -232,7 +232,16 @@
return err
}
}
- if err := writeAny(w, fv.Index(j), props); err != nil {
+ v := fv.Index(j)
+ if v.Kind() == reflect.Ptr && v.IsNil() {
+ // A nil message in a repeated field is not valid,
+ // but we can handle that more gracefully than panicking.
+ if _, err := w.Write([]byte("<nil>\n")); err != nil {
+ return err
+ }
+ continue
+ }
+ if err := writeAny(w, v, props); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
diff --git a/proto/text_test.go b/proto/text_test.go
index 4b76720..224a484 100644
--- a/proto/text_test.go
+++ b/proto/text_test.go
@@ -385,3 +385,24 @@
}
}
}
+
+func TestRepeatedNilText(t *testing.T) {
+ m := &pb.MessageList{
+ Message: []*pb.MessageList_Message{
+ nil,
+ &pb.MessageList_Message{
+ Name: proto.String("Horse"),
+ },
+ nil,
+ },
+ }
+ want := `Message <nil>
+Message {
+ name: "Horse"
+}
+Message <nil>
+`
+ if s := proto.MarshalTextString(m); s != want {
+ t.Errorf(" got: %s\nwant: %s", s, want)
+ }
+}