From fdfbb5b3a5f0211b2ed456a865a2b02a9265ebd4 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 15 Sep 2023 16:37:54 +0200 Subject: [PATCH 1/3] Escape placeholder before injecting it into the style In particular this adds escaping for backslashes which was previously missing. --- src/components/views/rooms/BasicMessageComposer.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/views/rooms/BasicMessageComposer.tsx b/src/components/views/rooms/BasicMessageComposer.tsx index c1db383dc18..2d21e9f616e 100644 --- a/src/components/views/rooms/BasicMessageComposer.tsx +++ b/src/components/views/rooms/BasicMessageComposer.tsx @@ -282,9 +282,7 @@ export default class BasicMessageEditor extends React.Component }; private showPlaceholder(): void { - // escape single quotes - const placeholder = this.props.placeholder?.replace(/'/g, "\\'"); - this.editorRef.current?.style.setProperty("--placeholder", `'${placeholder}'`); + this.editorRef.current?.style.setProperty("--placeholder", `'${CSS.escape(this.props.placeholder ?? "")}'`); this.editorRef.current?.classList.add("mx_BasicMessageComposer_inputEmpty"); } From 238dc4d1a83d82cd0579cad76da7d4d88d985d18 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 18 Sep 2023 12:35:40 +0200 Subject: [PATCH 2/3] Update snapshots --- .../structures/__snapshots__/RoomView-test.tsx.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/components/structures/__snapshots__/RoomView-test.tsx.snap b/test/components/structures/__snapshots__/RoomView-test.tsx.snap index 19df74f76d6..8df509e7ed0 100644 --- a/test/components/structures/__snapshots__/RoomView-test.tsx.snap +++ b/test/components/structures/__snapshots__/RoomView-test.tsx.snap @@ -446,7 +446,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] = data-testid="basicmessagecomposer" dir="auto" role="textbox" - style="--placeholder: 'Send a message…';" + style="--placeholder: 'Send\\ a\\ message…';" tabindex="0" translate="no" > @@ -687,7 +687,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t data-testid="basicmessagecomposer" dir="auto" role="textbox" - style="--placeholder: 'Send a message…';" + style="--placeholder: 'Send\\ a\\ message…';" tabindex="0" translate="no" > From 8f19611be29f8fd4b9abbe8f609b30331856358b Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 18 Sep 2023 13:04:42 +0200 Subject: [PATCH 3/3] Add tests --- .../views/rooms/BasicMessageComposer-test.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/components/views/rooms/BasicMessageComposer-test.tsx b/test/components/views/rooms/BasicMessageComposer-test.tsx index 4215ce6e643..eb25cef8676 100644 --- a/test/components/views/rooms/BasicMessageComposer-test.tsx +++ b/test/components/views/rooms/BasicMessageComposer-test.tsx @@ -94,6 +94,22 @@ describe("BasicMessageComposer", () => { const transformedText = model.parts.map((part) => part.text).join(""); expect(transformedText).toBe("/plain foobar\n"); }); + + it("should escape single quote in placeholder", async () => { + const model = new EditorModel([], pc, renderer); + const composer = render(); + const input = composer.queryAllByRole("textbox"); + const placeholder = input[0].style.getPropertyValue("--placeholder"); + expect(placeholder).toMatch("'Don\\'t'"); + }); + + it("should escape backslash in placeholder", async () => { + const model = new EditorModel([], pc, renderer); + const composer = render(); + const input = composer.queryAllByRole("textbox"); + const placeholder = input[0].style.getPropertyValue("--placeholder"); + expect(placeholder).toMatch("'w\\\\e'"); + }); }); function generateMockDataTransferForString(string: string): DataTransfer {