Treat member labels as unset if they can't be decrypted.

This commit is contained in:
jeffrey-signal
2026-03-12 17:33:54 -04:00
committed by GitHub
parent df89f8879d
commit 55e029e81d
2 changed files with 82 additions and 4 deletions

View File

@@ -769,8 +769,8 @@ public final class GroupsV2Operations {
modifyMemberLabels.add(
new DecryptedModifyMemberLabel.Builder()
.aciBytes(decryptAciToBinary(action.userId))
.labelEmoji(Objects.requireNonNullElse(decryptString(action.labelEmoji), ""))
.labelString(Objects.requireNonNullElse(decryptString(action.labelString), ""))
.labelEmoji(decryptMemberLabelEmoji(action.labelEmoji))
.labelString(decryptMemberLabelText(action.labelString))
.build()
);
}
@@ -817,8 +817,8 @@ public final class GroupsV2Operations {
private DecryptedMember.Builder decryptMember(Member member)
throws InvalidGroupStateException, VerificationFailedException, InvalidInputException
{
String labelEmoji = Objects.requireNonNullElse(decryptString(member.labelEmoji), "");
String labelString = Objects.requireNonNullElse(decryptString(member.labelString), "");
String labelEmoji = decryptMemberLabelEmoji(member.labelEmoji);
String labelString = decryptMemberLabelText(member.labelString);
if (member.presentation.size() == 0) {
ACI aci = decryptAci(member.userId);
@@ -1072,6 +1072,26 @@ public final class GroupsV2Operations {
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
@Nonnull
private String decryptMemberLabelText(@Nullable ByteString cipherText) {
try {
return Objects.requireNonNullElse(decryptString(cipherText), "");
} catch (VerificationFailedException e) {
Log.w(TAG, "Failed to decrypt member label string, treating as unset");
return "";
}
}
@Nonnull
private String decryptMemberLabelEmoji(@Nullable ByteString cipherText) {
try {
return Objects.requireNonNullElse(decryptString(cipherText), "");
} catch (VerificationFailedException e) {
Log.w(TAG, "Failed to decrypt member label emoji, treating as unset");
return "";
}
}
/**
* Verifies signature and parses actions on a group change.
*/

View File

@@ -476,6 +476,64 @@ public final class GroupsV2Operations_decrypt_change_Test {
);
}
@Test
public void member_label_text_is_treated_as_unset_on_decryption_error_field26() {
ACI aci = ACI.from(UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001"));
ByteString invalidBytes = ByteString.of(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 });
GroupChange.Actions.Builder change = new GroupChange.Actions.Builder()
.modifyMemberLabels(
List.of(
new GroupChange.Actions.ModifyMemberLabelAction.Builder()
.userId(groupOperations.encryptServiceId(aci))
.labelString(invalidBytes)
.build()
)
);
DecryptedGroupChange.Builder expected = new DecryptedGroupChange.Builder()
.modifyMemberLabels(
List.of(
new DecryptedModifyMemberLabel.Builder()
.aciBytes(aci.toByteString())
.labelEmoji("")
.labelString("")
.build()
)
);
assertDecryption(change, expected);
}
@Test
public void member_label_emoji_is_treated_as_unset_on_decryption_error_field26() {
ACI aci = ACI.from(UUID.fromString("d1d1d1d1-0000-4000-8000-000000000001"));
ByteString invalidBytes = ByteString.of(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 });
GroupChange.Actions.Builder change = new GroupChange.Actions.Builder()
.modifyMemberLabels(
List.of(
new GroupChange.Actions.ModifyMemberLabelAction.Builder()
.userId(groupOperations.encryptServiceId(aci))
.labelEmoji(invalidBytes)
.build()
)
);
DecryptedGroupChange.Builder expected = new DecryptedGroupChange.Builder()
.modifyMemberLabels(
List.of(
new DecryptedModifyMemberLabel.Builder()
.aciBytes(aci.toByteString())
.labelEmoji("")
.labelString("")
.build()
)
);
assertDecryption(change, expected);
}
@Test
public void can_pass_through_new_member_label_access_field_27() {
GroupChange.Actions.Builder encryptedChange = groupOperations.createChangeMemberLabelRights(AccessControl.AccessRequired.ADMINISTRATOR);