From b857283ed6476e4fa09a82e606f910d4af9439b8 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Wed, 27 Aug 2025 03:16:27 -0400 Subject: [PATCH] Fix `skipItemUpdate` logic in Item#relinkAttachmentFile() We were skipping updating of `clientDateModified` in order to prevent an attachment item upload, but that hasn't been used since Zotero 4. This might mean that, in some rare situations (e.g., a filename that needed to be shortened due to filesystem path length?), people in read-only or non-files-editable groups may have ended up triggering access errors and needing to reset local data after a file download. Now, we properly skip marking the attachment item as unsynced. --- chrome/content/zotero/xpcom/data/item.js | 8 +++----- chrome/content/zotero/xpcom/storage/storageLocal.js | 9 ++++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 570ca6abad..0578175725 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -2939,10 +2939,8 @@ Zotero.Item.prototype.renameAttachmentFile = async function (newName, overwrite /** * @param {string} path File path - * @param {Boolean} [skipItemUpdate] Don't update attachment item mod time, so that item doesn't - * sync. Used when a file needs to be renamed to be accessible but the user doesn't have - * access to modify the attachment metadata. This also allows a save when the library is - * read-only. + * @param {Boolean} [skipItemUpdate] Don't mark item as unsynced. Used when a file needs to be + * renamed to be accessible but the user doesn't have access to modify the attachment metadata. */ Zotero.Item.prototype.relinkAttachmentFile = async function (path, skipItemUpdate) { if (path instanceof Components.interfaces.nsIFile) { @@ -3028,7 +3026,7 @@ Zotero.Item.prototype.relinkAttachmentFile = async function (path, skipItemUpdat await this.saveTx({ skipDateModifiedUpdate: true, - skipClientDateModifiedUpdate: skipItemUpdate, + skipSyncedUpdate: skipItemUpdate, skipEditCheck: skipItemUpdate }); diff --git a/chrome/content/zotero/xpcom/storage/storageLocal.js b/chrome/content/zotero/xpcom/storage/storageLocal.js index 149d5c9a05..8fdac5aa04 100644 --- a/chrome/content/zotero/xpcom/storage/storageLocal.js +++ b/chrome/content/zotero/xpcom/storage/storageLocal.js @@ -598,16 +598,15 @@ Zotero.Sync.Storage.Local = { } // If newPath is set, the file was renamed, so set item filename to that - // and mark for updated + // and mark item for upload var path = await item.getFilePathAsync(); if (newPath && path != newPath) { - // If library isn't editable but filename was changed, update - // database without updating the item's mod time, which would result - // in a library access error + // If library isn't editable but filename was changed, update database without marking + // item as unsynced try { if (!Zotero.Items.isEditable(item)) { Zotero.debug("File renamed without library access -- " - + "updating itemAttachments path", 3); + + "updating attachment path", 3); await item.relinkAttachmentFile(newPath, true); } else {