diff --git a/Cargo.lock b/Cargo.lock index ccdbaff29..ae181a31e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1879,6 +1879,7 @@ name = "wysiwyg-wasm" version = "2.37.8" dependencies = [ "console_error_panic_hook", + "html-escape", "js-sys", "wasm-bindgen", "wasm-bindgen-futures", diff --git a/bindings/wysiwyg-wasm/Cargo.toml b/bindings/wysiwyg-wasm/Cargo.toml index 68802cc0d..4a72f0538 100644 --- a/bindings/wysiwyg-wasm/Cargo.toml +++ b/bindings/wysiwyg-wasm/Cargo.toml @@ -26,6 +26,7 @@ crate-type = ["cdylib"] [dependencies] console_error_panic_hook = "0.1.7" +html-escape = "0.2.11" js-sys = "0.3.60" wasm-bindgen = "0.2.83" wasm-bindgen-futures = "0.4.33" diff --git a/bindings/wysiwyg-wasm/src/lib.rs b/bindings/wysiwyg-wasm/src/lib.rs index 1b5b30f74..9791007eb 100644 --- a/bindings/wysiwyg-wasm/src/lib.rs +++ b/bindings/wysiwyg-wasm/src/lib.rs @@ -327,7 +327,7 @@ impl ComposerModel { ) -> ComposerUpdate { ComposerUpdate::from(self.inner.set_link_with_text( Utf16String::from_str(url), - Utf16String::from_str(text), + Utf16String::from_str(&html_escape::encode_safe(&text)), attributes.into_vec(), )) } @@ -360,7 +360,7 @@ impl ComposerModel { ) -> ComposerUpdate { ComposerUpdate::from(self.inner.insert_mention( Utf16String::from_str(url), - Utf16String::from_str(text), + Utf16String::from_str(&html_escape::encode_safe(&text)), attributes.into_vec(), )) } @@ -389,7 +389,7 @@ impl ComposerModel { ) -> ComposerUpdate { ComposerUpdate::from(self.inner.insert_mention_at_suggestion( Utf16String::from_str(url), - Utf16String::from_str(text), + Utf16String::from_str(&html_escape::encode_safe(&text)), wysiwyg::SuggestionPattern::from(suggestion.clone()), attributes.into_vec(), )) diff --git a/platforms/web/lib/suggestion.test.tsx b/platforms/web/lib/suggestion.test.tsx index 0e4a12e78..0bb790bb9 100644 --- a/platforms/web/lib/suggestion.test.tsx +++ b/platforms/web/lib/suggestion.test.tsx @@ -14,7 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { SuggestionPattern } from '../generated/wysiwyg'; +import init, { + // eslint-disable-next-line camelcase + new_composer_model, + SuggestionPattern, +} from '../generated/wysiwyg'; import { SUGGESTIONS } from './constants'; import { getSuggestionChar, @@ -22,6 +26,10 @@ import { mapSuggestion, } from './suggestion'; +beforeAll(async () => { + await init(); +}); + describe('getSuggestionChar', () => { it('returns the expected character', () => { SUGGESTIONS.forEach((suggestionCharacter, index) => { @@ -92,3 +100,30 @@ describe('mapSuggestion', () => { }); }); }); + +describe('suggestionPattern', () => { + it('Content should be encoded', () => { + // Given + const model = new_composer_model(); + model.replace_text('hello '); + const update = model.replace_text('@alic'); + const suggestion = update.menu_action().suggestion(); + + // When + if (!suggestion) { + fail('There should be an suggestion!'); + } + + model.insert_mention_at_suggestion( + 'https://matrix.to/#/@alice:matrix.org', + ':D a broken mention!', + suggestion.suggestion_pattern, + new Map(), + ); + + // Then + expect(model.get_content_as_html()).toBe( + 'hello :D</a> a broken mention!\u{a0}', + ); + }); +});