Reject attachments with unrecognized CDN numbers instead of crashing.
This commit is contained in:
parent
6ea96795cb
commit
812a858761
@ -41,12 +41,16 @@ enum class Cdn(private val value: Int) {
|
||||
}
|
||||
|
||||
fun fromCdnNumber(cdnNumber: Int): Cdn {
|
||||
return fromCdnNumberOrNull(cdnNumber) ?: throw UnsupportedOperationException("Invalid CDN number: $cdnNumber")
|
||||
}
|
||||
|
||||
fun fromCdnNumberOrNull(cdnNumber: Int): Cdn? {
|
||||
return when (cdnNumber) {
|
||||
-1 -> S3
|
||||
0 -> CDN_0
|
||||
2 -> CDN_2
|
||||
3 -> CDN_3
|
||||
else -> throw UnsupportedOperationException("Invalid CDN number: $cdnNumber")
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import android.os.Parcel
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import org.signal.blurhash.BlurHash
|
||||
import org.signal.core.util.Base64
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.whispersystems.signalservice.api.InvalidMessageStructureException
|
||||
@ -76,6 +77,8 @@ class PointerAttachment : Attachment {
|
||||
override val thumbnailUri: Uri? = null
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(PointerAttachment::class)
|
||||
|
||||
@JvmStatic
|
||||
fun forPointers(pointers: Optional<List<SignalServiceAttachment>>): List<Attachment> {
|
||||
if (!pointers.isPresent) {
|
||||
@ -102,6 +105,13 @@ class PointerAttachment : Attachment {
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
val cdnNumber = pointer.get().asPointer().cdnNumber
|
||||
val cdn = Cdn.fromCdnNumberOrNull(cdnNumber)
|
||||
if (cdn == null) {
|
||||
Log.w(TAG, "Encountered an attachment pointer with an unsupported CDN number ($cdnNumber). Skipping attachment.")
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
val encodedKey: String? = pointer.get().asPointer().key?.let { Base64.encodeWithPadding(it) }
|
||||
|
||||
return Optional.of(
|
||||
@ -110,7 +120,7 @@ class PointerAttachment : Attachment {
|
||||
transferState = transferState,
|
||||
size = pointer.get().asPointer().size.orElse(0).toLong(),
|
||||
fileName = pointer.get().asPointer().fileName.orElse(null),
|
||||
cdn = Cdn.fromCdnNumber(pointer.get().asPointer().cdnNumber),
|
||||
cdn = cdn,
|
||||
location = pointer.get().asPointer().remoteId.toString(),
|
||||
key = encodedKey,
|
||||
iv = null,
|
||||
@ -145,7 +155,13 @@ class PointerAttachment : Attachment {
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
val cdn = Cdn.fromCdnNumber(thumbnail?.asPointer()?.cdnNumber ?: 0)
|
||||
val cdnNumber = thumbnail?.asPointer()?.cdnNumber ?: 0
|
||||
val cdn = Cdn.fromCdnNumberOrNull(cdnNumber)
|
||||
if (cdn == null) {
|
||||
Log.w(TAG, "Encountered a quote thumbnail with an unsupported CDN number ($cdnNumber). Skipping attachment.")
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
if (cdn == Cdn.S3) {
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import org.signal.archive.proto.FilePointer
|
||||
import org.signal.core.util.Base64
|
||||
import org.signal.core.util.UuidUtil
|
||||
import org.signal.core.util.isNotNullOrBlank
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.nullIfBlank
|
||||
import org.signal.core.util.orNull
|
||||
import org.signal.libsignal.usernames.BaseUsernameException
|
||||
@ -32,6 +33,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemo
|
||||
import java.util.Optional
|
||||
import org.signal.archive.proto.AvatarColor as RemoteAvatarColor
|
||||
|
||||
private const val TAG = "ArchiveConverter"
|
||||
|
||||
/**
|
||||
* Converts a [FilePointer] to a local [Attachment] object for inserting into the database.
|
||||
*/
|
||||
@ -58,10 +61,16 @@ fun FilePointer?.toLocalAttachment(
|
||||
|
||||
return when (attachmentType) {
|
||||
AttachmentType.ARCHIVE -> {
|
||||
val cdnNumber = locatorInfo.transitCdnNumber ?: Cdn.CDN_0.cdnNumber
|
||||
if (Cdn.fromCdnNumberOrNull(cdnNumber) == null) {
|
||||
Log.w(TAG, "Encountered an archived attachment with an unsupported CDN number ($cdnNumber). Skipping attachment.")
|
||||
return null
|
||||
}
|
||||
|
||||
ArchivedAttachment(
|
||||
contentType = contentType,
|
||||
size = locatorInfo.size.toLong(),
|
||||
cdn = locatorInfo.transitCdnNumber ?: Cdn.CDN_0.cdnNumber,
|
||||
cdn = cdnNumber,
|
||||
uploadTimestamp = locatorInfo.transitTierUploadTimestamp ?: 0,
|
||||
key = locatorInfo.key.toByteArray(),
|
||||
cdnKey = locatorInfo.transitCdnKey?.nullIfBlank(),
|
||||
|
||||
@ -119,13 +119,15 @@ public class ContactModelMapper {
|
||||
if (contact.avatar != null && contact.avatar.avatar != null) {
|
||||
try {
|
||||
SignalServiceAttachmentPointer attachmentPointer = AttachmentPointerUtil.createSignalAttachmentPointer(contact.avatar.avatar);
|
||||
Attachment attachment = PointerAttachment.forPointer(Optional.of(attachmentPointer.asPointer())).get();
|
||||
Optional<Attachment> attachment = PointerAttachment.forPointer(Optional.of(attachmentPointer.asPointer()));
|
||||
|
||||
if (attachment.cdn == Cdn.S3) {
|
||||
if (!attachment.isPresent()) {
|
||||
Log.w(TAG, "Unable to create avatar attachment for contact. Ignoring avatar.");
|
||||
} else if (attachment.get().cdn == Cdn.S3) {
|
||||
Log.w(TAG, "Ignoring contact avatar that resolves to the internal release-channel CDN.");
|
||||
} else {
|
||||
boolean isProfile = Boolean.TRUE.equals(contact.avatar.isProfile);
|
||||
avatar = new Avatar(null, attachment, isProfile);
|
||||
avatar = new Avatar(null, attachment.get(), isProfile);
|
||||
}
|
||||
} catch (InvalidMessageStructureException e) {
|
||||
Log.w(TAG, "Unable to create avatar for contact", e);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user