mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-24 19:56:00 +00:00
Keep remote fields in sync when deduping downloads.
This commit is contained in:
@@ -12,9 +12,12 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.signal.core.util.Base64
|
||||
import org.signal.core.util.readFully
|
||||
import org.signal.core.util.stream.LimitedInputStream
|
||||
import org.signal.core.util.update
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentId
|
||||
import org.thoughtcrime.securesms.attachments.Cdn
|
||||
import org.thoughtcrime.securesms.attachments.PointerAttachment
|
||||
import org.thoughtcrime.securesms.backup.v2.BackupRepository.getMediaName
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable.TransformProperties
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -30,6 +33,7 @@ import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
|
||||
import org.whispersystems.signalservice.api.backup.MediaId
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import kotlin.random.Random
|
||||
@@ -378,6 +382,37 @@ class AttachmentTableTest_deduping {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun downloads() {
|
||||
// Normal attachment download that dupes with an existing attachment
|
||||
test {
|
||||
val id1 = insertWithData(DATA_A)
|
||||
upload(id1)
|
||||
|
||||
val id2 = insertUndownloadedPlaceholder()
|
||||
download(id2, DATA_A)
|
||||
|
||||
assertDataFilesAreTheSame(id1, id2)
|
||||
assertDataHashEndMatches(id1, id2)
|
||||
assertRemoteFieldsMatch(id1, id2)
|
||||
assertArchiveFieldsMatch(id1, id2)
|
||||
}
|
||||
|
||||
// Attachment download that dupes with an existing attachment, but has bad padding
|
||||
test {
|
||||
val id1 = insertWithData(DATA_A)
|
||||
upload(id1)
|
||||
|
||||
val id2 = insertUndownloadedPlaceholder()
|
||||
download(id2, DATA_A, properPadding = false)
|
||||
|
||||
assertDataFilesAreTheSame(id1, id2)
|
||||
assertDataHashEndMatches(id1, id2)
|
||||
assertRemoteFieldsMatch(id1, id2)
|
||||
assertArchiveFieldsMatch(id1, id2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Various deletion scenarios to ensure that duped files don't deleted while there's still references.
|
||||
*/
|
||||
@@ -614,6 +649,39 @@ class AttachmentTableTest_deduping {
|
||||
}
|
||||
|
||||
private class TestContext {
|
||||
fun insertUndownloadedPlaceholder(): AttachmentId {
|
||||
return SignalDatabase.attachments.insertAttachmentsForMessage(
|
||||
mmsId = 1,
|
||||
attachments = listOf(
|
||||
PointerAttachment(
|
||||
contentType = "image/jpeg",
|
||||
transferState = AttachmentTable.TRANSFER_PROGRESS_PENDING,
|
||||
size = 100,
|
||||
fileName = null,
|
||||
cdn = Cdn.CDN_3,
|
||||
location = "somelocation",
|
||||
key = Base64.encodeWithPadding(Util.getSecretBytes(64)),
|
||||
iv = null,
|
||||
digest = Util.getSecretBytes(64),
|
||||
incrementalDigest = null,
|
||||
incrementalMacChunkSize = 0,
|
||||
fastPreflightId = null,
|
||||
voiceNote = false,
|
||||
borderless = false,
|
||||
videoGif = false,
|
||||
width = 100,
|
||||
height = 100,
|
||||
uploadTimestamp = System.currentTimeMillis(),
|
||||
caption = null,
|
||||
stickerLocator = null,
|
||||
blurHash = null,
|
||||
uuid = UUID.randomUUID()
|
||||
)
|
||||
),
|
||||
quoteAttachment = emptyList()
|
||||
).values.first()
|
||||
}
|
||||
|
||||
fun insertWithData(data: ByteArray, transformProperties: TransformProperties = TransformProperties.empty()): AttachmentId {
|
||||
val uri = BlobProvider.getInstance().forData(data).createForSingleSessionInMemory()
|
||||
|
||||
@@ -675,6 +743,22 @@ class AttachmentTableTest_deduping {
|
||||
)
|
||||
}
|
||||
|
||||
fun download(attachmentId: AttachmentId, data: ByteArray, properPadding: Boolean = true) {
|
||||
val paddedData = if (properPadding) {
|
||||
PaddingInputStream(data.inputStream(), data.size.toLong()).readFully()
|
||||
} else {
|
||||
val badPadding = ByteArray(16) { 42 }
|
||||
data + badPadding
|
||||
}
|
||||
|
||||
SignalDatabase.attachments.finalizeAttachmentAfterDownload(
|
||||
mmsId = 1,
|
||||
attachmentId = attachmentId,
|
||||
inputStream = LimitedInputStream(paddedData.inputStream(), data.size.toLong()),
|
||||
iv = Util.getSecretBytes(16)
|
||||
)
|
||||
}
|
||||
|
||||
fun delete(attachmentId: AttachmentId) {
|
||||
SignalDatabase.attachments.deleteAttachment(attachmentId)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user