From 75e6a77bdf39f3c2edcd342b48357b7f8a719481 Mon Sep 17 00:00:00 2001 From: automated-signal <37887102+automated-signal@users.noreply.github.com> Date: Mon, 13 Apr 2026 11:56:53 -0500 Subject: [PATCH] A few improvements for the save attachment workflow Co-authored-by: Scott Nonnenberg --- ts/state/ducks/conversations.preload.ts | 16 ++++++++++++++-- ts/test-node/util/isFileDangerous_test.std.ts | 7 +++++++ ts/util/isFileDangerous.std.ts | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ts/state/ducks/conversations.preload.ts b/ts/state/ducks/conversations.preload.ts index eff3ea1dc3..4af6a54efd 100644 --- a/ts/state/ducks/conversations.preload.ts +++ b/ts/state/ducks/conversations.preload.ts @@ -4121,7 +4121,13 @@ function saveAttachment( return async dispatch => { const { fileName = '' } = attachment; - const isDangerous = isFileDangerous(fileName); + const isDangerous = isFileDangerous( + fileName || + Attachment.getSuggestedFilename({ + attachment, + scenario: 'saving-locally', + }) + ); if (isDangerous) { dispatch({ @@ -4186,7 +4192,13 @@ function saveAttachments( for (const attachment of attachments) { const { fileName = '' } = attachment; - const isDangerous = isFileDangerous(fileName); + const isDangerous = isFileDangerous( + fileName || + Attachment.getSuggestedFilename({ + attachment, + scenario: 'saving-locally', + }) + ); if (isDangerous) { dispatch({ type: SHOW_TOAST, diff --git a/ts/test-node/util/isFileDangerous_test.std.ts b/ts/test-node/util/isFileDangerous_test.std.ts index dbc2062e9e..e1422e7845 100644 --- a/ts/test-node/util/isFileDangerous_test.std.ts +++ b/ts/test-node/util/isFileDangerous_test.std.ts @@ -49,6 +49,13 @@ describe('isFileDangerous', () => { assert.strictEqual(isFileDangerous('install.pif\t\n\n\n '), true); }); + it('returns true for dangerous files that end in combination of . and whitespace', () => { + assert.strictEqual(isFileDangerous('run.exe . . .... '), true); + assert.strictEqual(isFileDangerous('install.pif .'), true); + assert.strictEqual(isFileDangerous('install.pif\t.\n . '), true); + assert.strictEqual(isFileDangerous('install.pif\t\n.\n\n .. .'), true); + }); + it('returns false for empty filename', () => { assert.strictEqual(isFileDangerous(''), false); }); diff --git a/ts/util/isFileDangerous.std.ts b/ts/util/isFileDangerous.std.ts index 291e5a0187..effce99f29 100644 --- a/ts/util/isFileDangerous.std.ts +++ b/ts/util/isFileDangerous.std.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only const DANGEROUS_FILE_TYPES = - /\.(ADE|ADP|APK|BAT|CAB|CHM|CMD|COM|CPL|DIAGCAB|DLL|DMG|EXE|HTA|INF|INS|ISP|JAR|JS|JSE|LIB|LNK|MDE|MHT|MSC|MSI|MSP|MST|NSH|PIF|PS1|PSC1|PSM1|PSRC|REG|SCR|SCT|SETTINGCONTENT-MS|SHB|SYS|VB|VBE|VBS|VXD|WSC|WSF|WSH)(\.|\s+)?$/i; + /\.(ADE|ADP|APK|BAT|CAB|CHM|CMD|COM|CPL|DIAGCAB|DLL|DMG|EXE|HTA|INF|INS|ISP|JAR|JS|JSE|LIB|LNK|MDE|MHT|MSC|MSI|MSP|MST|NSH|PIF|PS1|PSC1|PSM1|PSRC|REG|SCR|SCT|SETTINGCONTENT-MS|SHB|SYS|VB|VBE|VBS|VXD|WSC|WSF|WSH)(\.|\s)*?$/i; export function isFileDangerous(fileName: string): boolean { return DANGEROUS_FILE_TYPES.test(fileName);