From 586c3b23e57e456d2a98165e95bf86dc6ea8e3ce Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Tue, 27 Jun 2023 18:39:13 +0200 Subject: [PATCH] fix: Only sanitize the built string There is no need to sanitize the replacement values as it is sufficient to sanitize the result. 1. This will improve the performance if multiple placeholders are used. 2. This allows this: `See {linkstart}documentation{linkend}` with `{ linkstart: '', linkend: '' }` while the string is still sanitized. Signed-off-by: Ferdinand Thiessen --- lib/translation.ts | 14 +++++++++----- tests/translation.test.ts | 6 ++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/translation.ts b/lib/translation.ts index 700f2e64..42b099d5 100644 --- a/lib/translation.ts +++ b/lib/translation.ts @@ -52,14 +52,18 @@ export function translate( const _build = (text: string, vars?: Record, number?: number) => { return text.replace(/%n/g, '' + number).replace(/{([^{}]*)}/g, (match, key) => { if (vars === undefined || !(key in vars)) { - return optSanitize(match) + return optEscape(match) } - const r = vars[key] - if (typeof r === 'string' || typeof r === 'number') { - return optSanitize(optEscape(r)) + const replacement = vars[key] + if (typeof replacement === 'string' || typeof replacement === 'number') { + return optEscape(`${replacement}`) } else { - return optSanitize(match) + /* This should not happen, + * but the variables are used defined so not allowed types could still be given, + * in this case ignore the replacement and use the placeholder + */ + return optEscape(match) } }) } diff --git a/tests/translation.test.ts b/tests/translation.test.ts index 3d3bf001..404d266d 100644 --- a/tests/translation.test.ts +++ b/tests/translation.test.ts @@ -42,6 +42,12 @@ describe('translate', () => { expect(translation).toBe('Hallo Name') }) + it('without placeholder HTML escaping on links', () => { + const text = 'Hello {start}Nextcloud{end}' + const translation = translate('core', text, { start: '', end: '' }, undefined, { escape: false }) + expect(translation).toBe('Hello Nextcloud') + }) + it('with placeholder HTML escaping', () => { const text = 'Hello {name}' const translation = translate('core', text, { name: 'Name' })