diff --git a/common/src/main/java/dev/cel/common/values/ProtoLiteCelValueConverter.java b/common/src/main/java/dev/cel/common/values/ProtoLiteCelValueConverter.java index 481392466..932bec658 100644 --- a/common/src/main/java/dev/cel/common/values/ProtoLiteCelValueConverter.java +++ b/common/src/main/java/dev/cel/common/values/ProtoLiteCelValueConverter.java @@ -138,7 +138,7 @@ private Object mergeOrReadMessageField( if (existingValue instanceof RawProtoMessageLiteValue) { bytes = ((RawProtoMessageLiteValue) existingValue).toByteString().concat(bytes); } - return RawProtoMessageLiteValue.create(bytes, fieldProtoTypeName, this); + return RawProtoMessageLiteValue.create(bytes, fieldProtoTypeName, this, /* isView= */ true); } WellKnownProto wellKnownProto = WellKnownProto.getByTypeName(fieldProtoTypeName).orElse(null); if (isStructLike(wellKnownProto)) { @@ -356,6 +356,8 @@ private Map.Entry readSingleMapEntry( @Nullable FieldLiteDescriptor keyDescriptor, @Nullable FieldLiteDescriptor valueDescriptor) { CodedInputStream inputStream = bytes.newCodedInput(); + // Submessages alias bytes; unwrapping parses or copies them, so no view outlives evaluation. + inputStream.enableAliasing(true); int targetFieldNumber = fieldDescriptor.getFieldNumber(); Object fieldValue = null; try { diff --git a/common/src/main/java/dev/cel/common/values/RawProtoMessageLiteValue.java b/common/src/main/java/dev/cel/common/values/RawProtoMessageLiteValue.java index aa1440522..8a34751cf 100644 --- a/common/src/main/java/dev/cel/common/values/RawProtoMessageLiteValue.java +++ b/common/src/main/java/dev/cel/common/values/RawProtoMessageLiteValue.java @@ -50,6 +50,9 @@ abstract class RawProtoMessageLiteValue extends StructValue out.writeInt32(1, 42)); + RawProtoMessageLiteValue raw = + RawProtoMessageLiteValue.create( + encode(out -> out.writeBytes(21, submessage)), EMPTY_CONVERTER); + SelectField field = + SelectField.create(21L, "single_nested_message", SelectField.MESSAGE_TYPE_CODE); + RawProtoMessageLiteValue selected = (RawProtoMessageLiteValue) raw.selectByFieldNumber(field); + + WireMessageLite value = selected.value(); + + assertThat(value).isNotSameInstanceAs(selected); + assertThat(value.toByteString()).isEqualTo(submessage); + } + @Test public void create_defaultsUnknownMessageTypeName() { ByteString bytes = ByteString.copyFromUtf8("test");