From cdf1f3c8566e233dce8dbd053b95d85fee78c61e Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 21 May 2021 02:52:01 -0400 Subject: [PATCH] Mendeley import: Use bytes for path/filename limits on Windows It's not totally clear how it's calculated, but it doesn't seem to be just characters. And make the path limit 255, which is the File Explorer limit, even if the filesystem can allow up to 260. --- .../zotero/import/mendeley/mendeleyImport.js | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/chrome/content/zotero/import/mendeley/mendeleyImport.js b/chrome/content/zotero/import/mendeley/mendeleyImport.js index e931b83105..2b7e637c69 100644 --- a/chrome/content/zotero/import/mendeley/mendeleyImport.js +++ b/chrome/content/zotero/import/mendeley/mendeleyImport.js @@ -706,18 +706,27 @@ Zotero_Import_Mendeley.prototype._getDocumentFilesAPI = async function (document for (let doc of documents) { const files = []; for (let file of (doc.files || [])) { - var fileName = Zotero.File.truncateFileName(Zotero.File.getValidFileName(file.file_name || 'file'), 255); // most filesystems limit filename to 255 characters - var tmpFile = OS.Path.join(Zotero.getTempDirectory().path, `m-api-${this.timestamp}-${file.id}`, fileName); + // Most filesystems limit filename to 255 bytes + let fileName = Zotero.File.truncateFileName(Zotero.File.getValidFileName(file.file_name || 'file'), 255); + let tmpFile = OS.Path.join(Zotero.getTempDirectory().path, `m-api-${this.timestamp}-${file.id}`, fileName); // Limit path length on Windows - if (Zotero.isWin && tmpFile.length >= 260) { - const surplus = tmpFile.length - 260; - if (surplus >= fileName.length) { - Zotero.logError(`File ${fileName} will be skipped due to path exceeding filesystem limits: ${tmpFile}`); - continue; + // + // This can be raised in Windows 10 but probably isn't for most people. The limit is + // theoretically 260, but File Explorer seems to limit paths to 255, so stick to that. + // https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + if (Zotero.isWin) { + let pathLength = Zotero.Utilities.Internal.byteLength(tmpFile); + if (pathLength >= 255) { + let surplus = pathLength - 255; + let fileNameLength = Zotero.Utilities.Internal.byteLength(fileName); + if (surplus >= fileNameLength) { + Zotero.logError(`Skipping file due to path exceeding filesystem limits: ${tmpFile}`); + continue; + } + Zotero.debug(`${fileName} will be truncated by ${surplus} bytes`); + fileName = Zotero.File.truncateFileName(fileName, fileNameLength - surplus); + tmpFile = OS.Path.join(Zotero.getTempDirectory().path, `m-api-${this.timestamp}-${file.id}`, fileName); } - Zotero.debug(`${fileName} will be truncated by ${surplus} characters`); - fileName = Zotero.File.truncateFileName(fileName, fileName.length - surplus); - tmpFile = OS.Path.join(Zotero.getTempDirectory().path, `m-api-${this.timestamp}-${file.id}`, fileName); } this._tmpFilesToDelete.push(tmpFile); caller.add(this._fetchFile.bind(this, file.id, tmpFile));