Validate usernames during backup export.

This commit is contained in:
Greyson Parrelli
2025-10-30 11:22:24 -04:00
committed by Michelle Tang
parent 587bfcb524
commit 8ac0c42f44
3 changed files with 19 additions and 17 deletions

View File

@@ -14,12 +14,11 @@ import org.signal.core.util.requireBoolean
import org.signal.core.util.requireInt
import org.signal.core.util.requireLong
import org.signal.core.util.requireString
import org.signal.libsignal.usernames.BaseUsernameException
import org.signal.libsignal.usernames.Username
import org.thoughtcrime.securesms.backup.v2.ArchiveRecipient
import org.thoughtcrime.securesms.backup.v2.proto.Contact
import org.thoughtcrime.securesms.backup.v2.proto.Self
import org.thoughtcrime.securesms.backup.v2.util.clampToValidBackupRange
import org.thoughtcrime.securesms.backup.v2.util.isValidUsername
import org.thoughtcrime.securesms.backup.v2.util.toRemote
import org.thoughtcrime.securesms.conversation.colors.AvatarColor
import org.thoughtcrime.securesms.database.IdentityTable
@@ -71,7 +70,7 @@ class ContactArchiveExporter(private val cursor: Cursor, private val selfId: Lon
val contactBuilder = Contact.Builder()
.aci(aci?.rawUuid?.toByteArray()?.toByteString())
.pni(pni?.rawUuid?.toByteArray()?.toByteString())
.username(cursor.requireString(RecipientTable.USERNAME).takeIf { isValidUsername(it) })
.username(cursor.requireString(RecipientTable.USERNAME)?.takeIf { it.isValidUsername() })
.e164(cursor.requireString(RecipientTable.E164)?.e164ToLong())
.blocked(cursor.requireBoolean(RecipientTable.BLOCKED))
.visibility(Recipient.HiddenState.deserialize(cursor.requireInt(RecipientTable.HIDDEN)).toRemote())
@@ -146,16 +145,3 @@ private fun String.e164ToLong(): Long? {
return fixed.toLongOrNull()?.takeUnless { it == 0L }
}
private fun isValidUsername(username: String?): Boolean {
if (username.isNullOrBlank()) {
return false
}
return try {
Username(username)
true
} catch (e: BaseUsernameException) {
false
}
}

View File

@@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.backup.v2.proto.Frame
import org.thoughtcrime.securesms.backup.v2.stream.BackupFrameEmitter
import org.thoughtcrime.securesms.backup.v2.util.ChatStyleConverter
import org.thoughtcrime.securesms.backup.v2.util.isValid
import org.thoughtcrime.securesms.backup.v2.util.isValidUsername
import org.thoughtcrime.securesms.backup.v2.util.parseChatWallpaper
import org.thoughtcrime.securesms.backup.v2.util.toLocal
import org.thoughtcrime.securesms.backup.v2.util.toLocalAttachment
@@ -78,7 +79,7 @@ object AccountDataArchiveProcessor {
familyName = selfRecord.signalProfileName.familyName,
avatarUrlPath = selfRecord.signalProfileAvatar ?: "",
svrPin = SignalStore.svr.pin ?: "",
username = selfRecord.username?.takeIf { it.isNotBlank() },
username = selfRecord.username?.takeIf { it.isValidUsername() },
usernameLink = if (selfRecord.username.isNotNullOrBlank() && signalStore.accountValues.usernameLink != null) {
AccountData.UsernameLink(
entropy = signalStore.accountValues.usernameLink?.entropy?.toByteString() ?: EMPTY,

View File

@@ -11,6 +11,8 @@ import org.signal.core.util.Base64
import org.signal.core.util.isNotNullOrBlank
import org.signal.core.util.nullIfBlank
import org.signal.core.util.orNull
import org.signal.libsignal.usernames.BaseUsernameException
import org.signal.libsignal.usernames.Username
import org.thoughtcrime.securesms.attachments.ArchivedAttachment
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.attachments.Cdn
@@ -251,6 +253,19 @@ private fun DatabaseAttachment.toRemoteAttachmentType(): AttachmentType {
return AttachmentType.INVALID
}
fun String.isValidUsername(): Boolean {
if (this.isBlank()) {
return false
}
return try {
Username(this)
true
} catch (e: BaseUsernameException) {
false
}
}
private enum class AttachmentType {
TRANSIT, ARCHIVE, INVALID
}