From c3df191a95e5a907655a6f9db6b8c2b70be47907 Mon Sep 17 00:00:00 2001
From: SFulpius <36622934+SFulpius@users.noreply.github.com>
Date: Tue, 12 Jul 2022 12:34:56 +0200
Subject: [PATCH] Desktop: Fixes #6570: Fixed broken image links (#6590)

---
 packages/lib/models/Note.test.ts | 34 ++++++++++++++++++++++++++++++++
 packages/lib/models/Note.ts      | 12 ++++++++---
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/packages/lib/models/Note.test.ts b/packages/lib/models/Note.test.ts
index 4ffdfbd7f0..a42e8ec25e 100644
--- a/packages/lib/models/Note.test.ts
+++ b/packages/lib/models/Note.test.ts
@@ -411,3 +411,37 @@ describe('models/Note', function() {
 	}));
 
 });
+
+describe('models/Note_replacePaths', function() {
+
+	function testResourceReplacment(body: string, pathsToTry: string[], expected: string) {
+		expect(Note['replaceResourceExternalToInternalLinks_'](pathsToTry, body)).toBe(expected);
+	}
+	test('Basic replacement', () => {
+		const body = '![image.png](file:///C:Users/Username/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
+		const pathsToTry = ['file:///C:Users/Username/resources'];
+		const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
+		testResourceReplacment(body, pathsToTry, expected);
+	});
+
+	test('Replacement with spaces', () => {
+		const body = '![image.png](file:///C:Users/Username%20with%20spaces/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
+		const pathsToTry = ['file:///C:Users/Username with spaces/resources'];
+		const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
+		testResourceReplacment(body, pathsToTry, expected);
+	});
+
+	test('Replacement with Non-ASCII', () => {
+		const body = '![image.png](file:///C:Users/UsernameWith%C3%A9%C3%A0%C3%B6/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
+		const pathsToTry = ['file:///C:Users/UsernameWithéàö/resources'];
+		const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
+		testResourceReplacment(body, pathsToTry, expected);
+	});
+
+	test('Replacement with Non-ASCII and spaces', () => {
+		const body = '![image.png](file:///C:Users/Username%20With%20%C3%A9%C3%A0%C3%B6/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
+		const pathsToTry = ['file:///C:Users/Username With éàö/resources'];
+		const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
+		testResourceReplacment(body, pathsToTry, expected);
+	});
+});
diff --git a/packages/lib/models/Note.ts b/packages/lib/models/Note.ts
index 5cd3941616..aa087e29ce 100644
--- a/packages/lib/models/Note.ts
+++ b/packages/lib/models/Note.ts
@@ -182,7 +182,7 @@ export default class Note extends BaseItem {
 
 		const resourceDir = toForwardSlashes(Setting.value('resourceDir'));
 
-		let pathsToTry = [];
+		const pathsToTry = [];
 		if (options.useAbsolutePaths) {
 			pathsToTry.push(`file://${resourceDir}`);
 			pathsToTry.push(`file:///${resourceDir}`);
@@ -192,6 +192,13 @@ export default class Note extends BaseItem {
 			pathsToTry.push(Resource.baseRelativeDirectoryPath());
 		}
 
+		body = Note.replaceResourceExternalToInternalLinks_(pathsToTry, body);
+		return body;
+	}
+
+	private static replaceResourceExternalToInternalLinks_(pathsToTry: string[], body: string) {
+		// This is a moved to a separate function for the purpose of testing only
+
 		// We support both the escaped and unescaped versions because both
 		// of those paths are valid:
 		//
@@ -202,7 +209,7 @@ export default class Note extends BaseItem {
 		const temp = [];
 		for (const p of pathsToTry) {
 			temp.push(p);
-			temp.push(markdownUtils.escapeLinkUrl(p));
+			temp.push(encodeURI(p));
 		}
 
 		pathsToTry = temp;
@@ -227,7 +234,6 @@ export default class Note extends BaseItem {
 			// Handles joplin://af0edffa4a60496bba1b0ba06b8fb39a
 			body = body.replace(/\(joplin:\/\/([a-zA-Z0-9]{32})\)/g, '(:/$1)');
 		}
-
 		// this.logger().debug('replaceResourceExternalToInternalLinks result', body);
 
 		return body;