Skip to content

Commit b76ee6a

Browse files
committed
fix(install-dynamic-plugins): address Sonar code-smell findings
Resolves the 21 issues flagged by SonarQube on PR #4574: Prototype pollution (CodeQL, merger.ts) - `deepMerge` now assigns via `Object.defineProperty` (bypasses the `__proto__` setter on `Object.prototype`) in addition to the existing `FORBIDDEN_KEYS` guard. CodeQL recognizes this pattern. Redundant type assertions - `index.ts:180`: drop `pc as Record<string, unknown>` — use the `isPlainObject` type guard already imported from `util.ts`. - `installer-npm.ts:37`, `installer-oci.ts:35`: replace `(plugin.pluginConfig ?? {}) as Record<string, unknown>` with a typed local variable. - `installer-oci.ts:41,51,71,78`: drop `as string` casts by restructuring the `isAlreadyInstalled` helper with proper `undefined` checks. - `merger.ts:136-140`: replace `.slice(-1)[0] as string` with `.at(-1) ?? ''`. - `merger.ts:215`: `ReadonlyArray<keyof Plugin | string>` collapses to `ReadonlyArray<string>`. Cognitive complexity reductions - `installOciPlugin` (17 → ~10): extract `resolvePullPolicy` and `isAlreadyInstalled` helpers. - `mergeOciPlugin` (20 → ~12): extract `resolveInherit`. - `npmPluginKey` (16 → ~7): extract `tryParseAlias`, `isGitLikeSpec`, `stripRefSuffix`. - `ociPluginKey`: extract `autoDetectPluginPath`. Modern JS / readability (es2015-es2022) - `integrity.ts`: `charCodeAt` → `codePointAt` (es2015). - `oci-key.ts`: use `String.raw` for the regex pieces containing `\s`, `\d`, `\]`, `\\` instead of escaped string literals (es2015). - `oci-key.ts:escape`: `.replace(/.../g, ...)` → `.replaceAll(...)` (es2021). - `plugin-hash.ts`: pass an explicit code-point comparator to `sort` so deterministic-hash behavior is spelled out. `localeCompare` is NOT used — it varies per-locale and would break hash stability. All 115 tests still pass. Bundle rebuilt (415.1 KB).
1 parent 3fce9fd commit b76ee6a

File tree

9 files changed

+351
-259
lines changed

9 files changed

+351
-259
lines changed

scripts/install-dynamic-plugins/dist/install-dynamic-plugins.cjs

Lines changed: 141 additions & 114 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/install-dynamic-plugins/src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,8 @@ function handleSkippedLocals(skipped: Plugin[], globalConfig: Record<string, unk
175175
for (const plugin of skipped) {
176176
const abs = path.join(process.cwd(), plugin.package.slice(2));
177177
log(`\t==> ${plugin.package} (not found at ${abs})`);
178-
const pc = plugin.pluginConfig;
179-
if (pc && typeof pc === 'object' && !Array.isArray(pc)) {
180-
deepMerge(pc as Record<string, unknown>, globalConfig);
178+
if (isPlainObject(plugin.pluginConfig)) {
179+
deepMerge(plugin.pluginConfig, globalConfig);
181180
}
182181
}
183182
}

scripts/install-dynamic-plugins/src/installer-npm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export async function installNpmPlugin(
3434
}
3535
const pkg = plugin.package;
3636
const force = plugin.forceDownload ?? false;
37-
const config = (plugin.pluginConfig ?? {}) as Record<string, unknown>;
37+
const config: Record<string, unknown> = plugin.pluginConfig ?? {};
3838

3939
if (installed.has(hash) && !force) {
4040
const pullPolicy = plugin.pullPolicy ?? PullPolicy.IF_NOT_PRESENT;

0 commit comments

Comments
 (0)