Update attachment handling

This commit is contained in:
trevor-signal 2024-12-11 14:56:41 -05:00 committed by GitHub
parent 6f7faf4be8
commit 6c348e2db7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 22 deletions

View file

@ -1,6 +1,6 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { debounce, noop, omit } from 'lodash';
import { noop, omit, throttle } from 'lodash';
import * as durations from '../util/durations';
import * as log from '../logging/log';
@ -46,7 +46,10 @@ import {
import type { MIMEType } from '../types/MIME';
import { AttachmentDownloadSource } from '../sql/Interface';
import { drop } from '../util/drop';
import { getAttachmentCiphertextLength } from '../AttachmentCrypto';
import {
getAttachmentCiphertextLength,
type ReencryptedAttachmentV2,
} from '../AttachmentCrypto';
import { safeParsePartial } from '../util/schemas';
import { createBatcher } from '../util/batcher';
@ -522,11 +525,15 @@ export async function runDownloadAttachmentJobInner({
try {
let totalDownloaded = 0;
let downloadedAttachment: ReencryptedAttachmentV2 | undefined;
const onSizeUpdate = async (totalBytes: number) => {
if (abortSignal.aborted) {
return;
}
if (downloadedAttachment) {
return;
}
totalDownloaded = Math.min(totalBytes, attachment.size);
await addAttachmentToMessage(
@ -537,18 +544,18 @@ export async function runDownloadAttachmentJobInner({
);
};
const downloaded = await dependencies.downloadAttachment({
downloadedAttachment = await dependencies.downloadAttachment({
attachment,
options: {
variant: AttachmentVariant.Default,
onSizeUpdate: debounce(onSizeUpdate, 200),
onSizeUpdate: throttle(onSizeUpdate, 200),
abortSignal,
},
});
const upgradedAttachment = await dependencies.processNewAttachment({
...omit(attachment, ['error', 'pending', 'downloadPath']),
...downloaded,
...downloadedAttachment,
});
await addAttachmentToMessage(messageId, upgradedAttachment, logId, {

View file

@ -5,7 +5,7 @@ import * as Bytes from '../Bytes';
import type { AttachmentDownloadJobTypeType } from '../types/AttachmentDownload';
import type { AttachmentType } from '../types/Attachment';
import { getAttachmentSignature, isDownloaded } from '../types/Attachment';
import { getAttachmentSignatureSafe, isDownloaded } from '../types/Attachment';
import { __DEPRECATED$getMessageById } from '../messages/getMessageById';
export async function addAttachmentToMessage(
@ -21,7 +21,10 @@ export async function addAttachmentToMessage(
return;
}
const attachmentSignature = getAttachmentSignature(attachment);
const attachmentSignature = getAttachmentSignatureSafe(attachment);
if (!attachmentSignature) {
log.error(`${logPrefix}: Attachment did not have valid signature (digest)`);
}
if (type === 'long-message') {
let handledAnywhere = false;
@ -45,7 +48,8 @@ export async function addAttachmentToMessage(
}
// This attachment isn't destined for this edit
if (
getAttachmentSignature(edit.bodyAttachment) !== attachmentSignature
getAttachmentSignatureSafe(edit.bodyAttachment) !==
attachmentSignature
) {
return edit;
}
@ -79,7 +83,8 @@ export async function addAttachmentToMessage(
return;
}
if (
getAttachmentSignature(existingBodyAttachment) !== attachmentSignature
getAttachmentSignatureSafe(existingBodyAttachment) !==
attachmentSignature
) {
return;
}
@ -116,7 +121,7 @@ export async function addAttachmentToMessage(
return existing;
}
if (attachmentSignature !== getAttachmentSignature(existing)) {
if (attachmentSignature !== getAttachmentSignatureSafe(existing)) {
return existing;
}
@ -322,7 +327,7 @@ export async function addAttachmentToMessage(
message.set({
sticker: {
...sticker,
data: attachment,
data: sticker.data ? maybeReplaceAttachment(sticker.data) : attachment,
},
});
return;

View file

@ -1105,6 +1105,16 @@ export function getAttachmentSignature(attachment: AttachmentType): string {
return attachment.digest;
}
export function getAttachmentSignatureSafe(
attachment: AttachmentType
): string | undefined {
try {
return getAttachmentSignature(attachment);
} catch {
return undefined;
}
}
type RequiredPropertiesForDecryption = 'key' | 'digest';
type RequiredPropertiesForReencryption = 'path' | 'key' | 'digest' | 'iv';

View file

@ -21,7 +21,7 @@ import type {
} from '../model-types.d';
import * as Errors from '../types/errors';
import {
getAttachmentSignature,
getAttachmentSignatureSafe,
isDownloading,
isDownloaded,
} from '../types/Attachment';
@ -44,16 +44,6 @@ export type MessageAttachmentsDownloadedType = {
sticker?: StickerType;
};
function getAttachmentSignatureSafe(
attachment: AttachmentType
): string | undefined {
try {
return getAttachmentSignature(attachment);
} catch {
return undefined;
}
}
function getLogger(source: AttachmentDownloadSource) {
const verbose = source !== AttachmentDownloadSource.BACKUP_IMPORT;
const log = verbose ? logger : { ...logger, info: () => null };