diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java index 0213fbc029..209f35eeb3 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -901,7 +901,11 @@ public class RubyMessage extends RubyObject { if (fdef.isRepeated()) { copy.fields.put(fdef, this.getRepeatedField(context, fdef).deepCopy(context)); } else if (fields.containsKey(fdef)) { - copy.setFieldInternal(context, fdef, fields.get(fdef)); + if (fdef.getType() == FieldDescriptor.Type.MESSAGE) { + copy.setFieldInternal(context, fdef, ((RubyMessage) fields.get(fdef)).deepCopy(context)); + } else { + copy.setFieldInternal(context, fdef, fields.get(fdef)); + } } else if (builder.hasField(fdef)) { copy.fields.put(fdef, wrapField(context, fdef, builder.getField(fdef))); } diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index 09ea4d8c83..28494f9c08 100644 --- a/ruby/tests/common_tests.rb +++ b/ruby/tests/common_tests.rb @@ -701,6 +701,15 @@ module CommonTests assert m.repeated_msg[0].object_id != m2.repeated_msg[0].object_id end + def test_sub_message_deep_copy # regression test for issue 12505 + m = proto_module::Foo.new(bar: proto_module::Bar.new(msg: "Hello World")) + m2 = Google::Protobuf.deep_copy(m) + assert_equal(m, m2) + assert_not_equal(m.object_id, m2.object_id) + assert_equal(m.bar, m2.bar) + assert_not_equal(m.bar.object_id, m2.bar.object_id) + end + def test_message_eq m = proto_module::TestMessage.new(:optional_int32 => 42, :repeated_int32 => [1, 2, 3])