From 95eaf94cd89c12c56eb2e909fb4d9a5c8092f27f Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Wed, 15 Apr 2020 00:40:38 +0100
Subject: [PATCH] Fix pills being broken by unescaped characters
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/editor/deserialize.js | 2 +-
src/editor/serialize.js | 2 +-
test/editor/deserialize-test.js | 16 ++++++++++++++++
test/editor/serialize-test.js | 12 ++++++++++++
4 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/editor/deserialize.js b/src/editor/deserialize.js
index 190963f357..d80a62b981 100644
--- a/src/editor/deserialize.js
+++ b/src/editor/deserialize.js
@@ -50,7 +50,7 @@ function parseLink(a, partCreator) {
if (href === a.textContent) {
return partCreator.plain(a.textContent);
} else {
- return partCreator.plain(`[${a.textContent}](${href})`);
+ return partCreator.plain(`[${a.textContent.replace(/[\\\]]/, c => "\\" + c)}](${href})`);
}
}
}
diff --git a/src/editor/serialize.js b/src/editor/serialize.js
index ba380f2809..341d92d3c8 100644
--- a/src/editor/serialize.js
+++ b/src/editor/serialize.js
@@ -30,7 +30,7 @@ export function mdSerialize(model) {
return html + part.text;
case "room-pill":
case "user-pill":
- return html + `[${part.text}](${makeGenericPermalink(part.resourceId)})`;
+ return html + `[${part.text.replace(/[\\\]]/, c => "\\" + c)}](${makeGenericPermalink(part.resourceId)})`;
}
}, "");
}
diff --git a/test/editor/deserialize-test.js b/test/editor/deserialize-test.js
index 1c58a6c40b..be8fe8aeab 100644
--- a/test/editor/deserialize-test.js
+++ b/test/editor/deserialize-test.js
@@ -148,6 +148,22 @@ describe('editor/deserialize', function() {
expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice", resourceId: "@alice:hs.tld"});
expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
});
+ it('user pill with displayname containing backslash', function() {
+ const html = "Hi Alice\!";
+ const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
+ expect(parts.length).toBe(3);
+ expect(parts[0]).toStrictEqual({type: "plain", text: "Hi "});
+ expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice\\", resourceId: "@alice:hs.tld"});
+ expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
+ });
+ it('user pill with displayname containing closing square bracket', function() {
+ const html = "Hi Alice]!";
+ const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
+ expect(parts.length).toBe(3);
+ expect(parts[0]).toStrictEqual({type: "plain", text: "Hi "});
+ expect(parts[1]).toStrictEqual({type: "user-pill", text: "Alice]", resourceId: "@alice:hs.tld"});
+ expect(parts[2]).toStrictEqual({type: "plain", text: "!"});
+ });
it('room pill', function() {
const html = "Try #room:hs.tld?";
const parts = normalize(parseEvent(htmlMessage(html), createPartCreator()));
diff --git a/test/editor/serialize-test.js b/test/editor/serialize-test.js
index 7517e46437..d5fb800600 100644
--- a/test/editor/serialize-test.js
+++ b/test/editor/serialize-test.js
@@ -43,4 +43,16 @@ describe('editor/serialize', function() {
const html = htmlSerializeIfNeeded(model, {});
expect(html).toBe("hello world");
});
+ it('displaynames ending in a backslash work', function () {
+ const pc = createPartCreator();
+ const model = new EditorModel([pc.userPill("Displayname\\", "@user:server")]);
+ const html = htmlSerializeIfNeeded(model, {});
+ expect(html).toBe("Displayname\");
+ });
+ it('displaynames containing a closing square bracket work', function () {
+ const pc = createPartCreator();
+ const model = new EditorModel([pc.userPill("Displayname]", "@user:server")]);
+ const html = htmlSerializeIfNeeded(model, {});
+ expect(html).toBe("Displayname]");
+ });
});