From f100809bf386c9c53e0d1c1e8f3149517862a883 Mon Sep 17 00:00:00 2001 From: Tiago Pereira Date: Tue, 8 Feb 2022 02:29:36 +0000 Subject: [PATCH] fix: escape strings.xml app name (#1384) --- lib/create.js | 2 +- lib/utils.js | 18 ++++++++++++++++++ spec/unit/create.spec.js | 7 +++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/create.js b/lib/create.js index fbbcf16a..da75631f 100755 --- a/lib/create.js +++ b/lib/create.js @@ -255,7 +255,7 @@ exports.create = function (project_path, config, options, events) { fs.ensureDirSync(activity_dir); fs.copySync(path.join(project_template_dir, 'Activity.java'), activity_path); utils.replaceFileContents(activity_path, /__ACTIVITY__/, safe_activity_name); - utils.replaceFileContents(path.join(app_path, 'res', 'values', 'strings.xml'), /__NAME__/, project_name); + utils.replaceFileContents(path.join(app_path, 'res', 'values', 'strings.xml'), /__NAME__/, utils.escape(project_name)); utils.replaceFileContents(activity_path, /__ID__/, package_name); var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml')); diff --git a/lib/utils.js b/lib/utils.js index 7436cac5..28f17d92 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -66,3 +66,21 @@ exports.forgivingWhichSync = (cmd) => { exports.isWindows = () => os.platform() === 'win32'; exports.isDarwin = () => os.platform() === 'darwin'; + +const UNESCAPED_REGEX = /[&<>"']/g; + +const escapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; + +/** + * Converts the characters "&", "<", ">", '"' and "'" in the given string to + * their corresponding escaped value + * @param {string} str the string to be escaped + * @returns the escaped string + */ +exports.escape = (str) => UNESCAPED_REGEX.test(str) ? str.replace(UNESCAPED_REGEX, (key) => escapes[key]) : str; diff --git a/spec/unit/create.spec.js b/spec/unit/create.spec.js index de05e866..33cc4bee 100644 --- a/spec/unit/create.spec.js +++ b/spec/unit/create.spec.js @@ -275,6 +275,13 @@ describe('create', function () { }); }); + it('should interpolate the escaped project name into strings.xml', () => { + config_mock.name.and.returnValue(''); + return create.create(project_path, config_mock, {}, events_mock).then(() => { + expect(utils.replaceFileContents).toHaveBeenCalledWith(path.join(app_path, 'res', 'values', 'strings.xml'), /__NAME__/, '<Incredible&App>'); + }); + }); + it('should copy template scripts into generated project', () => { return create.create(project_path, config_mock, {}, events_mock).then(() => { expect(create.copyScripts).toHaveBeenCalledWith(project_path);