[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);
diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb index 3eafe09..ea042eb 100755 --- a/ruby/tests/well_known_types_test.rb +++ b/ruby/tests/well_known_types_test.rb
@@ -193,4 +193,12 @@ assert_equal false, s['b'][:y] assert_equal false, s[:b]['y'] end + + def test_b8325 + value_field = Google::Protobuf::ListValue.descriptor.lookup("values") + proto = Google::Protobuf::ListValue.new( + values: [Google::Protobuf::Value.new(string_value: "Hello")] + ) + assert_equal '[<Google::Protobuf::Value: string_value: "Hello">]', value_field.get(proto).inspect + end end