Fix Utilities.Internal.md5Async() on missing files and empty strings
https://forums.zotero.org/discussion/114208/zotero-7-beta-bug-report-consistent-error-when-syncing
This commit is contained in:
		
					parent
					
						
							
								8f2bf50cec
							
						
					
				
			
			
				commit
				
					
						85f58cc97d
					
				
			
		
					 2 changed files with 37 additions and 9 deletions
				
			
		|  | @ -139,14 +139,28 @@ Zotero.Utilities.Internal = { | ||||||
| 	 | 	 | ||||||
| 	/** | 	/** | ||||||
| 	 * @param {nsIFile|String} file  File or file path | 	 * @param {nsIFile|String} file  File or file path | ||||||
| 	 * @param {Boolean} [base64=FALSE]  Return as base-64-encoded string |  | ||||||
| 	 *                                  rather than hex string |  | ||||||
| 	 */ | 	 */ | ||||||
| 	md5Async: async function (file, base64) { | 	md5Async: async function (file) { | ||||||
| 		function toHexString(charCode) { | 		function toHexString(charCode) { | ||||||
| 			return ("0" + charCode.toString(16)).slice(-2); | 			return ("0" + charCode.toString(16)).slice(-2); | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
|  | 		var file = Zotero.File.pathToFile(file); | ||||||
|  | 		try { | ||||||
|  | 			let { size } = await IOUtils.stat(file.path); | ||||||
|  | 			if (size === 0) { | ||||||
|  | 				// MD5 for empty string
 | ||||||
|  | 				return "d41d8cd98f00b204e9800998ecf8427e"; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		catch (e) { | ||||||
|  | 			// Return false for missing files
 | ||||||
|  | 			if (e.name == "NotFoundError") { | ||||||
|  | 				return false; | ||||||
|  | 			} | ||||||
|  | 			throw e; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
| 		var ch = Components.classes["@mozilla.org/security/hash;1"] | 		var ch = Components.classes["@mozilla.org/security/hash;1"] | ||||||
| 			.createInstance(Components.interfaces.nsICryptoHash); | 			.createInstance(Components.interfaces.nsICryptoHash); | ||||||
| 		ch.init(ch.MD5); | 		ch.init(ch.MD5); | ||||||
|  | @ -156,12 +170,8 @@ Zotero.Utilities.Internal = { | ||||||
| 				.createInstance(Ci.nsIFileInputStream); | 				.createInstance(Ci.nsIFileInputStream); | ||||||
| 			is.init(Zotero.File.pathToFile(file), -1, -1, Ci.nsIFileInputStream.CLOSE_ON_EOF); | 			is.init(Zotero.File.pathToFile(file), -1, -1, Ci.nsIFileInputStream.CLOSE_ON_EOF); | ||||||
| 			ch.updateFromStream(is, -1); | 			ch.updateFromStream(is, -1); | ||||||
| 			let hash = ch.finish(base64); | 			// Get binary string and convert to hex string
 | ||||||
| 			// Base64
 | 			let hash = ch.finish(false); | ||||||
| 			if (base64) { |  | ||||||
| 				return hash; |  | ||||||
| 			} |  | ||||||
| 			// Hex string
 |  | ||||||
| 			let hexStr = ""; | 			let hexStr = ""; | ||||||
| 			for (let i = 0; i < hash.length; i++) { | 			for (let i = 0; i < hash.length; i++) { | ||||||
| 				hexStr += toHexString(hash.charCodeAt(i)); | 				hexStr += toHexString(hash.charCodeAt(i)); | ||||||
|  |  | ||||||
|  | @ -44,6 +44,24 @@ describe("Zotero.Utilities.Internal", function () { | ||||||
| 			 | 			 | ||||||
| 			yield OS.File.remove(file); | 			yield OS.File.remove(file); | ||||||
| 		}); | 		}); | ||||||
|  | 		 | ||||||
|  | 		it("should return false for a nonexistent file", async function () { | ||||||
|  | 			var tmpDir = Zotero.getTempDirectory().path; | ||||||
|  | 			var file = OS.Path.join(tmpDir, 'nonexistent-asawefaweoihafa'); | ||||||
|  | 			await assert.eventually.isFalse(ZUI.md5Async(file)); | ||||||
|  | 		}); | ||||||
|  | 		 | ||||||
|  | 		it("should return hash for an empty file", async function () { | ||||||
|  | 			const emptyHash = 'd41d8cd98f00b204e9800998ecf8427e'; | ||||||
|  | 			 | ||||||
|  | 			var tmpDir = Zotero.getTempDirectory().path; | ||||||
|  | 			var file = OS.Path.join(tmpDir, 'empty-file'); | ||||||
|  | 			await IOUtils.write(file, new Uint8Array()); | ||||||
|  | 			 | ||||||
|  | 			await assert.eventually.equal(ZUI.md5Async(file), emptyHash); | ||||||
|  | 			 | ||||||
|  | 			await IOUtils.remove(file); | ||||||
|  | 		}); | ||||||
| 	}) | 	}) | ||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Stillman
				Dan Stillman