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]"); + }); });