proto: fix memory aliasing bug in Reset
Fix a bug where using Message.Range alone does not clear
memory references for empty, but allocated lists and maps.
Thus, we iterate over every known field and explicitly call Clear.
Change-Id: I9c1847d4056cf66f3199947150f3140d0783444a
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/183197
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/proto/reset.go b/proto/reset.go
index fd8b786..f14d9ae 100644
--- a/proto/reset.go
+++ b/proto/reset.go
@@ -14,11 +14,18 @@
}
func resetMessage(m protoreflect.Message) {
+ // Clear all known fields.
+ fds := m.Descriptor().Fields()
+ for i := 0; i < fds.Len(); i++ {
+ m.Clear(fds.Get(i))
+ }
+
+ // Clear extension fields.
m.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
m.Clear(fd)
return true
})
- if m.GetUnknown() != nil {
- m.SetUnknown(nil)
- }
+
+ // Clear unknown fields.
+ m.SetUnknown(nil)
}