[Ruby] Fix for FieldDescriptor.get(msg).
This fix is similar to the previous bug found in
Message.[]. The fix is the same: we need to handle
arrays and maps properly.
Fixes: https://github.com/protocolbuffers/protobuf/issues/8325
diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c
index 6cf8174..10ded86 100644
--- a/ruby/ext/google/protobuf_c/defs.c
+++ b/ruby/ext/google/protobuf_c/defs.c
@@ -960,16 +960,14 @@
static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_msgdef *m;
- const upb_msgdef *msg = Message_Get(msg_rb, &m);
- VALUE arena = Message_GetArena(msg_rb);
- upb_msgval msgval;
+
+ Message_Get(msg_rb, &m);
if (m != upb_fielddef_containingtype(self->fielddef)) {
rb_raise(cTypeError, "get method called on wrong message type");
}
- msgval = upb_msg_get(msg, self->fielddef);
- return Convert_UpbToRuby(msgval, TypeInfo_get(self->fielddef), arena);
+ return Message_getfield(msg_rb, self->fielddef);
}
/*
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index 259f5e6..77b0e8b 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -292,7 +292,7 @@
upb_msg_set(msg, f, msgval, arena);
}
-static VALUE Message_getfield(VALUE _self, const upb_fielddef* f) {
+VALUE Message_getfield(VALUE _self, const upb_fielddef* f) {
Message* self = ruby_to_Message(_self);
// This is a special-case: upb_msg_mutable() for map & array are logically
// const (they will not change what is serialized) but physically
diff --git a/ruby/ext/google/protobuf_c/message.h b/ruby/ext/google/protobuf_c/message.h
index 551f41f..2ec440c 100644
--- a/ruby/ext/google/protobuf_c/message.h
+++ b/ruby/ext/google/protobuf_c/message.h
@@ -63,6 +63,9 @@
// object will reference |arena| and ensure that it outlives this object.
VALUE Message_GetRubyWrapper(upb_msg* msg, const upb_msgdef* m, VALUE arena);
+// Gets the given field from this message.
+VALUE Message_getfield(VALUE _self, const upb_fielddef* f);
+
// Implements #inspect for this message, printing the text to |b|.
void Message_PrintMessage(StringBuilder* b, const upb_msg* msg,
const upb_msgdef* m);