Fix mutability bug in Java proto lite: sub-messages inside of oneofs were not

being set as immutable. This would allow code to get a builder for a
sub-message and modify the original (supposedly immutable) copy.

PiperOrigin-RevId: 511598810
pull/12022/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent dbd5ae8593
commit fa82155c65
  1. 6
      java/core/src/main/java/com/google/protobuf/MessageSchema.java
  2. 24
      java/lite/src/test/java/com/google/protobuf/LiteTest.java
  3. 1
      src/google/protobuf/unittest_lite.proto

@ -5510,6 +5510,12 @@ final class MessageSchema<T> implements Schema<T> {
getMessageFieldSchema(pos).makeImmutable(UNSAFE.getObject(message, offset));
}
break;
case 60: // ONEOF_MESSAGE
case 68: // ONEOF_GROUP
if (isOneofPresent(message, numberAt(pos), pos)) {
getMessageFieldSchema(pos).makeImmutable(UNSAFE.getObject(message, offset));
}
break;
case 18: // DOUBLE_LIST:
case 19: // FLOAT_LIST:
case 20: // INT64_LIST:

@ -190,6 +190,18 @@ public class LiteTest {
}
}
@Test
public void testParsedOneofSubMessageIsImmutable() throws InvalidProtocolBufferException {
TestAllTypesLite message =
TestAllTypesLite.parseFrom(
TestAllTypesLite.newBuilder()
.setOneofNestedMessage(NestedMessage.newBuilder().addDd(1234).build())
.build()
.toByteArray());
IntArrayList subList = (IntArrayList) message.getOneofNestedMessage().getDdList();
assertThat(subList.isModifiable()).isFalse();
}
@Test
public void testMemoization() throws Exception {
GeneratedMessageLite<?, ?> message = TestUtilLite.getAllLiteExtensionsSet();
@ -2365,8 +2377,7 @@ public class LiteTest {
Foo fooWithOnlyValue = Foo.newBuilder().setValue(1).build();
Foo fooWithValueAndExtension =
fooWithOnlyValue
.toBuilder()
fooWithOnlyValue.toBuilder()
.setValue(1)
.setExtension(Bar.fooExt, Bar.newBuilder().setName("name").build())
.build();
@ -2382,8 +2393,7 @@ public class LiteTest {
Foo fooWithOnlyValue = Foo.newBuilder().setValue(1).build();
Foo fooWithValueAndExtension =
fooWithOnlyValue
.toBuilder()
fooWithOnlyValue.toBuilder()
.setValue(1)
.setExtension(Bar.fooExt, Bar.newBuilder().setName("name").build())
.build();
@ -2515,9 +2525,9 @@ public class LiteTest {
assertWithMessage("expected exception").fail();
} catch (InvalidProtocolBufferException expected) {
assertThat(
TestAllExtensionsLite.newBuilder()
.setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
.build())
TestAllExtensionsLite.newBuilder()
.setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
.build())
.isEqualTo(expected.getUnfinishedMessage());
}
}

@ -47,6 +47,7 @@ message TestAllTypesLite {
message NestedMessage {
optional int32 bb = 1;
optional int64 cc = 2;
repeated int32 dd = 3 [packed = true];
}
message NestedMessage2 {

Loading…
Cancel
Save