mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Fix potential NPE when reading old attachments.
This commit is contained in:
@@ -1626,13 +1626,7 @@ class AttachmentTable(
|
||||
.from(TABLE_NAME)
|
||||
.where("$ID = ?", attachmentId.id)
|
||||
.run()
|
||||
.readToSingleObject { cursor ->
|
||||
if (cursor.isNull(DATA_FILE) || cursor.isNull(DATA_RANDOM)) {
|
||||
null
|
||||
} else {
|
||||
cursor.readDataFileInfo()
|
||||
}
|
||||
}
|
||||
.readToSingleObject { cursor -> cursor.readDataFileInfo() }
|
||||
}
|
||||
|
||||
fun getThumbnailFileInfo(attachmentId: AttachmentId): ThumbnailFileInfo? {
|
||||
@@ -2289,6 +2283,7 @@ class AttachmentTable(
|
||||
.where("$DATA_FILE NOT NULL AND ($DATA_HASH_START = ? OR $DATA_HASH_END = ?)", fileWriteResult.hash, fileWriteResult.hash)
|
||||
.run()
|
||||
.readToList { it.readDataFileInfo() }
|
||||
.filterNotNull()
|
||||
.sortedByDescending { it.uploadTimestamp }
|
||||
.firstOrNull { existingMatch ->
|
||||
areTransformationsCompatible(
|
||||
@@ -2493,12 +2488,15 @@ class AttachmentTable(
|
||||
return getAttachment(this)
|
||||
}
|
||||
|
||||
private fun Cursor.readDataFileInfo(): DataFileInfo {
|
||||
private fun Cursor.readDataFileInfo(): DataFileInfo? {
|
||||
val filePath: String = this.requireString(DATA_FILE) ?: return null
|
||||
val random: ByteArray = this.requireBlob(DATA_RANDOM) ?: return null
|
||||
|
||||
return DataFileInfo(
|
||||
id = AttachmentId(this.requireLong(ID)),
|
||||
file = File(this.requireNonNullString(DATA_FILE)),
|
||||
file = File(filePath),
|
||||
length = this.requireLong(DATA_SIZE),
|
||||
random = this.requireNonNullBlob(DATA_RANDOM),
|
||||
random = random,
|
||||
hashStart = this.requireString(DATA_HASH_START),
|
||||
hashEnd = this.requireString(DATA_HASH_END),
|
||||
transformProperties = TransformProperties.parse(this.requireString(TRANSFORM_PROPERTIES)),
|
||||
|
||||
@@ -152,7 +152,7 @@ class FastJobStorage(private val jobDatabase: JobDatabase) : JobStorage {
|
||||
override fun getJobsInQueue(queue: String): List<JobSpec> {
|
||||
return minimalJobs
|
||||
.filter { it.queueKey == queue }
|
||||
.map { it.toJobSpec() }
|
||||
.mapNotNull { it.toJobSpec() }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -310,8 +310,8 @@ class FastJobStorage(private val jobDatabase: JobDatabase) : JobStorage {
|
||||
val deleteIds: Set<String> = ids.toSet()
|
||||
minimalJobs.removeIf { deleteIds.contains(it.id) }
|
||||
jobSpecCache.keys.removeAll(deleteIds)
|
||||
eligibleJobs.removeAll(jobsToDelete)
|
||||
migrationJobs.removeAll(jobsToDelete)
|
||||
eligibleJobs.removeIf { deleteIds.contains(it.id) }
|
||||
migrationJobs.removeIf { deleteIds.contains(it.id) }
|
||||
|
||||
mostEligibleJobForQueue.keys.removeAll(affectedQueues)
|
||||
|
||||
@@ -422,7 +422,7 @@ class FastJobStorage(private val jobDatabase: JobDatabase) : JobStorage {
|
||||
// We only want a single job from each queue. It should be the oldest job with the highest priority.
|
||||
if (job.priority > existingJobInQueue.priority || (job.priority == existingJobInQueue.priority && job.createTime < existingJobInQueue.createTime)) {
|
||||
mostEligibleJobForQueue[job.queueKey] = job
|
||||
eligibleJobs.remove(existingJobInQueue)
|
||||
eligibleJobs.removeIf { it.id == existingJobInQueue.id }
|
||||
} else {
|
||||
// There's a more eligible job in the queue already, so no need to put it in the eligible list
|
||||
jobToPlace = null
|
||||
@@ -453,10 +453,10 @@ class FastJobStorage(private val jobDatabase: JobDatabase) : JobStorage {
|
||||
}
|
||||
|
||||
if (updated.queueKey == Job.Parameters.MIGRATION_QUEUE_KEY) {
|
||||
migrationJobs.remove(current)
|
||||
migrationJobs.removeIf { it.id == current.id }
|
||||
migrationJobs += updated
|
||||
} else {
|
||||
eligibleJobs.remove(current)
|
||||
eligibleJobs.removeIf { current.id == it.id }
|
||||
current.queueKey?.let { queueKey ->
|
||||
if (mostEligibleJobForQueue[queueKey] == current) {
|
||||
mostEligibleJobForQueue.remove(queueKey)
|
||||
@@ -514,9 +514,9 @@ class FastJobStorage(private val jobDatabase: JobDatabase) : JobStorage {
|
||||
* Converts a [MinimalJobSpec] to a [JobSpec]. We prefer using the cache, but if it's not found, we'll hit the database.
|
||||
* We consider this a "recent access" and will cache it for future use.
|
||||
*/
|
||||
private fun MinimalJobSpec.toJobSpec(): JobSpec {
|
||||
private fun MinimalJobSpec.toJobSpec(): JobSpec? {
|
||||
return jobSpecCache.getOrPut(this.id) {
|
||||
jobDatabase.getJobSpec(this.id) ?: throw IllegalArgumentException("JobSpec not found for id: $id")
|
||||
jobDatabase.getJobSpec(this.id) ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user