From f681730e75792b10cac7a90b7b28ef1419866b4d Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Tue, 2 Jun 2009 11:13:41 +0000 Subject: [PATCH] - Automatically check for and remove invalid characters in filenames on a sync upload error - Add newline and characters not valid in XML (mostly control characters) to filename blacklist - Strip invalid characters when user is renaming a file manually --- chrome/content/zotero/xpcom/data/item.js | 2 ++ chrome/content/zotero/xpcom/file.js | 4 +++ chrome/content/zotero/xpcom/sync.js | 34 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index dc409bc946..5220eba523 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -2516,6 +2516,8 @@ Zotero.Item.prototype.renameAttachmentFile = function(newName, overwrite) { } try { + newName = Zotero.File.getValidFileName(newName); + if (file.leafName == newName) { return true; } diff --git a/chrome/content/zotero/xpcom/file.js b/chrome/content/zotero/xpcom/file.js index 5c61b3dbf8..6a12a785a5 100644 --- a/chrome/content/zotero/xpcom/file.js +++ b/chrome/content/zotero/xpcom/file.js @@ -215,6 +215,10 @@ Zotero.File = new function(){ // TODO: use space instead, and figure out what's doing extra // URL encode when saving attachments that trigger this fileName = fileName.replace(/[\/\\\?%\*:|"<>]/g, ''); + // Replace newlines (which shouldn't be in the string in the first place) with spaces + fileName = fileName.replace(/\n/g, ' '); + // Strip characters not valid in XML, since they won't sync and they're probably unwanted + fileName = fileName.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\ud800-\udfff\ufffe\uffff]/g, ''); // Don't allow blank filename if (!fileName) { fileName = '_'; diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js index b73fe49467..68365d8e94 100644 --- a/chrome/content/zotero/xpcom/sync.js +++ b/chrome/content/zotero/xpcom/sync.js @@ -1467,6 +1467,40 @@ Zotero.Sync.Server = new function () { if (firstChild.localName == 'error') { switch (firstChild.getAttribute('code')) { + case 'INVALID_UPLOAD_DATA': + // On the off-chance that this error is due to invalid characters + // in a filename, check them all (since getting a more specific + // error from the server would be difficult) + var sql = "SELECT itemID FROM itemAttachments WHERE linkMode IN (?,?)"; + var ids = Zotero.DB.columnQuery(sql, [Zotero.Attachments.LINK_MODE_IMPORTED_FILE, Zotero.Attachments.LINK_MODE_IMPORTED_URL]); + if (ids) { + var items = Zotero.Items.get(ids); + var rolledBack = false; + for each(var item in items) { + var file = item.getFile(); + if (!file) { + continue; + } + try { + var fn = file.leafName; + // TODO: move stripping logic (copied from _xmlize()) to Utilities + var xmlfn = file.leafName.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\ud800-\udfff\ufffe\uffff]/g, ''); + if (fn != xmlfn) { + if (!rolledBack) { + Zotero.DB.rollbackAllTransactions(); + } + Zotero.debug("Changing invalid filename to " + xmlfn); + item.renameAttachmentFile(xmlfn); + } + } + catch (e) { + Zotero.debug(e); + Components.utils.reportError(e); + } + } + } + break; + case 'ITEM_MISSING': var [libraryID, key] = firstChild.getAttribute('missingItem').split('/'); if (libraryID == Zotero.libraryID) {