From 83981c98b22e4bbfc554f2b810ac8b6eac3de48c Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 22 Nov 2024 08:07:02 -0800 Subject: [PATCH] fix: Various issues identified by code scanning (#1508) * fix: Various issues identified by code scanning * chore(ci): Update RAT action --- .github/workflows/release-audit.yml | 2 +- lib/Podfile.js | 4 +- lib/build.js | 3 +- lib/listEmulatorBuildTargets.js | 2 +- lib/plugman/pluginHandlers.js | 3 +- package-lock.json | 2 +- package.json | 6 +-- tests/spec/createAndBuild.spec.js | 12 +++--- tests/spec/unit/Plugman/common.spec.js | 11 ++++-- tests/spec/unit/Plugman/pluginHandler.spec.js | 7 +++- tests/spec/unit/build.spec.js | 10 +++-- tests/spec/unit/create.spec.js | 12 +++--- tests/spec/unit/prepare.spec.js | 38 +++++++++++-------- tests/spec/unit/projectFile.spec.js | 7 +++- 14 files changed, 70 insertions(+), 49 deletions(-) diff --git a/.github/workflows/release-audit.yml b/.github/workflows/release-audit.yml index afc296ff00..c2f6a3caad 100644 --- a/.github/workflows/release-audit.yml +++ b/.github/workflows/release-audit.yml @@ -34,7 +34,7 @@ jobs: - uses: actions/checkout@v4 # Check license headers - - uses: erisu/apache-rat-action@555ae80334a535eb6c1f8920b121563a5a985a75 + - uses: erisu/apache-rat-action@v1 # Setup environment with node - uses: actions/setup-node@v4 diff --git a/lib/Podfile.js b/lib/Podfile.js index 6f95851978..9fcb84b1c2 100644 --- a/lib/Podfile.js +++ b/lib/Podfile.js @@ -160,7 +160,7 @@ Podfile.prototype.__parseForPods = function (text) { }; Podfile.prototype.escapeSingleQuotes = function (string) { - return string.replace(/'/g, '\\\''); + return string.replaceAll("'", "\\'"); }; Podfile.prototype.getTemplate = function () { @@ -178,8 +178,6 @@ Podfile.prototype.getTemplate = function () { Podfile.prototype.addSpec = function (name, spec) { name = name || ''; - // optional - spec = spec; /* eslint no-self-assign : 0 */ if (!name.length) { // blank names are not allowed throw new CordovaError('Podfile addSpec: name is not specified.'); diff --git a/lib/build.js b/lib/build.js index 4458db1e2f..2d92e84448 100644 --- a/lib/build.js +++ b/lib/build.js @@ -457,8 +457,7 @@ function parseBuildFlag (buildFlag, args) { // If the flag starts with a '-' then it is an xcodebuild built-in option or a // user-defined setting. The regex makes sure that we don't split a user-defined // setting that is wrapped in quotes. - /* eslint-disable no-useless-escape */ - if (buildFlag[0] === '-' && !buildFlag.match(/^.*=(\".*\")|(\'.*\')$/)) { + if (buildFlag[0] === '-' && !buildFlag.match(/^[^=]+=(["'])(.*?[^\\])\1$/)) { args.otherFlags = args.otherFlags.concat(buildFlag.split(' ')); events.emit('warn', util.format('Adding xcodebuildArg: %s', buildFlag.split(' '))); } else { diff --git a/lib/listEmulatorBuildTargets.js b/lib/listEmulatorBuildTargets.js index 0377c9e71a..5dea5157b0 100644 --- a/lib/listEmulatorBuildTargets.js +++ b/lib/listEmulatorBuildTargets.js @@ -37,7 +37,7 @@ function listEmulatorBuildTargets () { const devices = simInfo.devices; const deviceTypes = simInfo.devicetypes; return deviceTypes.reduce(function (typeAcc, deviceType) { - if (!deviceType.name.match(/^[iPad|iPhone]/)) { + if (!deviceType.name.match(/^(iPad|iPhone)/)) { // ignore targets we don't support (like Apple Watch or Apple TV) return typeAcc; } diff --git a/lib/plugman/pluginHandlers.js b/lib/plugman/pluginHandlers.js index 859dc217a7..572fba4e51 100644 --- a/lib/plugman/pluginHandlers.js +++ b/lib/plugman/pluginHandlers.js @@ -305,9 +305,8 @@ function uninstallHelper (type, obj, project_dir, plugin_id, options, project) { } } -const pathSepFix = new RegExp(path.sep.replace(/\\/, '\\\\'), 'g'); function fixPathSep (file) { - return file.replace(pathSepFix, '/'); + return file.replaceAll(path.sep, path.posix.sep); } function copyFile (plugin_dir, src, project_dir, dest, link) { diff --git a/package-lock.json b/package-lock.json index 4014ba197e..c46fa3e8f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "jasmine": "^5.2.0", "nyc": "^17.0.0", "rewire": "^7.0.0", - "tmp": "^0.2.1" + "tmp": "^0.2.3" }, "engines": { "node": ">=16.13.0" diff --git a/package.json b/package.json index 432d43202c..b445a4d0ff 100644 --- a/package.json +++ b/package.json @@ -35,20 +35,20 @@ "jasmine": "^5.2.0", "nyc": "^17.0.0", "rewire": "^7.0.0", - "tmp": "^0.2.1" + "tmp": "^0.2.3" }, "engines": { "node": ">=16.13.0" }, "dependencies": { "cordova-common": "^5.0.0", + "elementtree": "^0.1.7", "execa": "^5.1.1", "ios-sim": "^8.0.2", "plist": "^3.0.6", "semver": "^7.4.0", "which": "^4.0.0", - "xcode": "^3.0.1", - "elementtree": "^0.1.7" + "xcode": "^3.0.1" }, "nyc": { "include": [ diff --git a/tests/spec/createAndBuild.spec.js b/tests/spec/createAndBuild.spec.js index 3643b54735..8f6c55beaf 100644 --- a/tests/spec/createAndBuild.spec.js +++ b/tests/spec/createAndBuild.spec.js @@ -18,16 +18,18 @@ */ const fs = require('node:fs'); -const os = require('node:os'); const path = require('node:path'); +const tmp = require('tmp'); const xcode = require('xcode'); const { ConfigParser } = require('cordova-common'); const create = require('../../lib/create'); -const makeTempDir = () => path.join( - fs.realpathSync(os.tmpdir()), - `cordova-ios-create-test-${Date.now()}` -); +tmp.setGracefulCleanup(); + +function makeTempDir () { + const tempdir = tmp.dirSync({ unsafeCleanup: true }); + return path.join(tempdir.name, `cordova-ios-create-test-${Date.now()}`); +} const templateConfigXmlPath = path.join(__dirname, '..', '..', 'templates', 'project', 'App', 'config.xml'); diff --git a/tests/spec/unit/Plugman/common.spec.js b/tests/spec/unit/Plugman/common.spec.js index 3621b4b777..e8498efc11 100644 --- a/tests/spec/unit/Plugman/common.spec.js +++ b/tests/spec/unit/Plugman/common.spec.js @@ -18,19 +18,22 @@ const fs = require('node:fs'); const path = require('node:path'); -const osenv = require('node:os'); +const tmp = require('tmp'); const rewire = require('rewire'); const common = rewire('../../../../lib/plugman/pluginHandlers'); -const test_dir = path.join(osenv.tmpdir(), 'test_plugman'); +tmp.setGracefulCleanup(); + +const tempdir = tmp.dirSync({ unsafeCleanup: true }); +const test_dir = path.join(tempdir.name, 'test_plugman'); const project_dir = path.join(test_dir, 'project'); const src = path.join(project_dir, 'src'); const dest = path.join(project_dir, 'dest'); const srcDirTree = path.join(src, 'one', 'two', 'three'); const srcFile = path.join(srcDirTree, 'test.java'); const symlink_file = path.join(srcDirTree, 'symlink'); -const non_plugin_file = path.join(osenv.tmpdir(), 'non_plugin_file'); +const non_plugin_file = path.join(tempdir.name, 'non_plugin_file'); const copyFile = common.__get__('copyFile'); const copyNewFile = common.__get__('copyNewFile'); @@ -167,7 +170,7 @@ function ignoreEPERMonWin32 (symlink_src, symlink_dest) { try { fs.symlinkSync(symlink_src, symlink_dest); } catch (e) { - if (process.platform === 'win32' && e.message.indexOf('Error: EPERM, operation not permitted' > -1)) { + if (process.platform === 'win32' && e.message.indexOf('Error: EPERM, operation not permitted') > -1) { return true; } throw e; diff --git a/tests/spec/unit/Plugman/pluginHandler.spec.js b/tests/spec/unit/Plugman/pluginHandler.spec.js index 9091fb7ac0..368f5f5a65 100644 --- a/tests/spec/unit/Plugman/pluginHandler.spec.js +++ b/tests/spec/unit/Plugman/pluginHandler.spec.js @@ -17,18 +17,21 @@ under the License. */ -const os = require('node:os'); const fs = require('node:fs'); const path = require('node:path'); const rewire = require('rewire'); const EventEmitter = require('node:events'); +const tmp = require('tmp'); + +tmp.setGracefulCleanup(); const PluginInfo = require('cordova-common').PluginInfo; const Api = require('../../../../lib/Api'); const projectFile = require('../../../../lib/projectFile'); const pluginHandlers = rewire('../../../../lib/plugman/pluginHandlers'); -const temp = path.join(os.tmpdir(), 'plugman'); +const tempdir = tmp.dirSync({ unsafeCleanup: true }); +const temp = path.join(tempdir.name, 'plugman'); const FIXTURES = path.join(__dirname, '..', 'fixtures'); const iosProject = path.join(FIXTURES, 'ios-config-xml'); diff --git a/tests/spec/unit/build.spec.js b/tests/spec/unit/build.spec.js index 21fd9f61d9..c9c81377f0 100644 --- a/tests/spec/unit/build.spec.js +++ b/tests/spec/unit/build.spec.js @@ -56,7 +56,9 @@ describe('build', () => { '-destination TestDestinationFlag', '-archivePath TestArchivePathFlag', 'CONFIGURATION_BUILD_DIR=TestConfigBuildDirFlag', - 'SHARED_PRECOMPS_DIR=TestSharedPrecompsDirFlag' + 'SHARED_PRECOMPS_DIR=TestSharedPrecompsDirFlag', + 'INFOPLIST_KEY_CFBundleDisplayName="My App Name"', + '-resultBundlePath="/tmp/result bundle/file"' ]; const args = getXcodeBuildArgs(testProjectPath, 'TestConfiguration', '', { device: true, buildFlag: buildFlags }); @@ -73,9 +75,11 @@ describe('build', () => { 'TestArchivePathFlag', 'archive', 'CONFIGURATION_BUILD_DIR=TestConfigBuildDirFlag', - 'SHARED_PRECOMPS_DIR=TestSharedPrecompsDirFlag' + 'SHARED_PRECOMPS_DIR=TestSharedPrecompsDirFlag', + 'INFOPLIST_KEY_CFBundleDisplayName="My App Name"', + '-resultBundlePath="/tmp/result bundle/file"' ]); - expect(args.length).toEqual(13); + expect(args.length).toEqual(15); }); it('should generate appropriate args for device', () => { diff --git a/tests/spec/unit/create.spec.js b/tests/spec/unit/create.spec.js index aa3e2f181d..609d8186bc 100644 --- a/tests/spec/unit/create.spec.js +++ b/tests/spec/unit/create.spec.js @@ -18,16 +18,18 @@ */ const fs = require('node:fs'); -const os = require('node:os'); const path = require('node:path'); +const tmp = require('tmp'); const xcode = require('xcode'); const { ConfigParser } = require('cordova-common'); const create = require('../../../lib/create'); -const makeTempDir = () => path.join( - fs.realpathSync(os.tmpdir()), - `cordova-ios-create-test-${Date.now()}` -); +tmp.setGracefulCleanup(); + +function makeTempDir () { + const tempdir = tmp.dirSync({ unsafeCleanup: true }); + return path.join(tempdir.name, `cordova-ios-create-test-${Date.now()}`); +} const templateConfigXmlPath = path.join(__dirname, '..', '..', '..', 'templates', 'project', 'App', 'config.xml'); diff --git a/tests/spec/unit/prepare.spec.js b/tests/spec/unit/prepare.spec.js index 0282b24ea9..afad29b2a4 100644 --- a/tests/spec/unit/prepare.spec.js +++ b/tests/spec/unit/prepare.spec.js @@ -22,6 +22,7 @@ const fs = require('node:fs'); const EventEmitter = require('node:events'); const path = require('node:path'); +const tmp = require('tmp'); const plist = require('plist'); const xcode = require('xcode'); const XcodeProject = xcode.project; @@ -31,30 +32,31 @@ const projectFile = require('../../../lib/projectFile'); const FileUpdater = require('cordova-common').FileUpdater; const versions = require('../../../lib/versions'); -const tmpDir = path.join(__dirname, '../../../tmp'); -const FIXTURES = path.join(__dirname, 'fixtures'); +tmp.setGracefulCleanup(); +const relativeTmp = path.join(__dirname, '..', '..', '..'); +const FIXTURES = path.join(__dirname, 'fixtures'); const iosProjectFixture = path.join(FIXTURES, 'ios-config-xml'); -const iosProject = path.join(tmpDir, 'prepare'); -const iosPlatform = path.join(iosProject, 'platforms/ios'); const ConfigParser = require('cordova-common').ConfigParser; describe('prepare', () => { let p; let Api; + let tempdir; + let iosProject; + beforeEach(() => { Api = rewire('../../../lib/Api'); - fs.mkdirSync(iosPlatform, { recursive: true }); + tempdir = tmp.dirSync({ tmpdir: relativeTmp, unsafeCleanup: true }); + iosProject = path.join(tempdir.name, 'prepare'); + const iosPlatform = path.join(iosProject, 'platforms/ios'); + fs.cpSync(iosProjectFixture, iosPlatform, { recursive: true }); p = new Api('ios', iosPlatform, new EventEmitter()); }); - afterEach(() => { - fs.rmSync(tmpDir, { recursive: true, force: true }); - }); - describe('launch storyboard feature (CB-9762)', () => { function makeSplashScreenEntry (src, width, height) { return { src, width, height }; @@ -271,9 +273,9 @@ describe('prepare', () => { describe('#getLaunchStoryboardImagesDir', () => { const getLaunchStoryboardImagesDir = prepare.__get__('getLaunchStoryboardImagesDir'); - const projectRoot = iosProject; it('should find the Assets.xcassets file in a project with an asset catalog', () => { + const projectRoot = iosProject; const platformProjDir = path.join('platforms', 'ios', 'App'); const assetCatalogPath = path.join(iosProject, platformProjDir, 'Assets.xcassets'); const expectedPath = path.join(platformProjDir, 'Assets.xcassets', 'LaunchStoryboard.imageset'); @@ -285,6 +287,7 @@ describe('prepare', () => { }); it('should NOT find the Assets.xcassets file in a project with no asset catalog', () => { + const projectRoot = iosProject; const platformProjDir = path.join('platforms', 'ios', 'SamplerApp'); const assetCatalogPath = path.join(iosProject, platformProjDir, 'Assets.xcassets'); @@ -2061,12 +2064,12 @@ describe('prepare', () => { spyOn(FileUpdater, 'mergeAndUpdateDir').and.returnValue(true); }); - const project = { - root: iosProject, - locations: { www: path.join(iosProject, 'www') } - }; - it('Test#021 : should update project-level www and with platform agnostic www and merges', () => { + const project = { + root: iosProject, + locations: { www: path.join(iosProject, 'www') } + }; + const merges_path = path.join(project.root, 'merges', 'ios'); fs.mkdirSync(merges_path, { recursive: true }); updateWww(project, p.locations); @@ -2077,6 +2080,11 @@ describe('prepare', () => { logFileOp); }); it('Test#022 : should skip merges if merges directory does not exist', () => { + const project = { + root: iosProject, + locations: { www: path.join(iosProject, 'www') } + }; + const merges_path = path.join(project.root, 'merges', 'ios'); fs.rmSync(merges_path, { recursive: true, force: true }); updateWww(project, p.locations); diff --git a/tests/spec/unit/projectFile.spec.js b/tests/spec/unit/projectFile.spec.js index 97a2ab129c..d4f7f7c779 100644 --- a/tests/spec/unit/projectFile.spec.js +++ b/tests/spec/unit/projectFile.spec.js @@ -17,12 +17,15 @@ under the License. */ -const os = require('node:os'); const path = require('node:path'); const fs = require('node:fs'); +const tmp = require('tmp'); const projectFile = require('../../../lib/projectFile'); -const iosProject = path.join(os.tmpdir(), 'plugman/projectFile'); +tmp.setGracefulCleanup(); + +const tempdir = tmp.dirSync({ unsafeCleanup: true }); +const iosProject = path.join(tempdir.name, 'plugman/projectFile'); const iosProjectFixture = path.join(__dirname, 'fixtures/ios-config-xml'); const locations = {