testing/protocmp: fix representation of empty bytes
The protoreflect API does not use the distinction between nil and non-nil
empty []byte to preserve presence. As such, avoid accidentally presenting
such information through the transformation.
Change-Id: Ia46b5e2d3fb534d7cd29f478ad47722bfaa06810
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/247458
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/testing/protocmp/xform.go b/testing/protocmp/xform.go
index d69bfb8..5a47d0f 100644
--- a/testing/protocmp/xform.go
+++ b/testing/protocmp/xform.go
@@ -296,6 +296,14 @@
return Enum{num: v.Enum(), ed: fd.Enum()}
case protoreflect.MessageKind, protoreflect.GroupKind:
return transformMessage(v.Message())
+ case protoreflect.BytesKind:
+ // The protoreflect API does not specify whether an empty bytes is
+ // guaranteed to be nil or not. Always return non-nil bytes to avoid
+ // leaking information about the concrete proto.Message implementation.
+ if len(v.Bytes()) == 0 {
+ return []byte{}
+ }
+ return v.Bytes()
default:
return v.Interface()
}
diff --git a/testing/protocmp/xform_test.go b/testing/protocmp/xform_test.go
index 7fc3f68..c6355d7 100644
--- a/testing/protocmp/xform_test.go
+++ b/testing/protocmp/xform_test.go
@@ -102,8 +102,8 @@
MapUint64Uint64: map[uint64]uint64{0: 64},
MapInt32Float: map[int32]float32{32: 32.32},
MapInt32Double: map[int32]float64{64: 64.64},
- MapStringString: map[string]string{"k": "v"},
- MapStringBytes: map[string][]byte{"k": []byte("v")},
+ MapStringString: map[string]string{"k": "v", "empty": ""},
+ MapStringBytes: map[string][]byte{"k": []byte("v"), "empty": nil},
MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{
"k": testpb.TestAllTypes_FOO,
},
@@ -120,8 +120,8 @@
"map_uint64_uint64": map[uint64]uint64{0: 64},
"map_int32_float": map[int32]float32{32: 32.32},
"map_int32_double": map[int32]float64{64: 64.64},
- "map_string_string": map[string]string{"k": "v"},
- "map_string_bytes": map[string][]byte{"k": []byte("v")},
+ "map_string_string": map[string]string{"k": "v", "empty": ""},
+ "map_string_bytes": map[string][]byte{"k": []byte("v"), "empty": []byte{}},
"map_string_nested_enum": map[string]Enum{
"k": enumOf(testpb.TestAllTypes_FOO),
},