enhance(#3624): local/no-exact-case-env-access — ratchet ADR-1703 onto production env reads (epic #3411 Phase 4) (#3976)
* enhance(#3624): local/no-exact-case-env-access — ratchet ADR-1703 onto production env reads (epic #3411 Phase 4) Extends ADR-1703's portability rule catalog with a second production-runtime rule: it flags an exact-case read of a Windows case-varying environment variable (PATH, PATHEXT, ComSpec, USERPROFILE, TEMP, TMP, APPDATA) off any receiver that is not process.env itself, matched via an env-shaped-receiver check to avoid colliding with ordinary `.path`-named properties elsewhere in the tree. Exports the seam's private `_envGet` as `envGet` so the rule's remediation message names a real helper, and fixes the one pre-existing violation the tightened rule found (`src/runtime-hooks-surface.cts`'s `env.APPDATA` read). Closes #3624 * fix(#3624): extractStaticName recognizes non-computed Literal destructuring keys; add missing accessor-call test case Review findings from the code-review + isolated-adversarial passes: - extractStaticName only matched non-computed Identifier keys, so a destructuring like `const { 'PATH': v } = opts.env;` (the issue's own I8 acceptance case) silently evaded the rule. Widened to accept a Literal key regardless of computed, which is safe for MemberExpression too (its non-computed property is always an Identifier by grammar). - Added the missing RuleTester valid case for "a case-insensitive accessor call" (envGet(env, 'PATH')) from the issue's Done-when checklist. * docs: backfill changeset PR number for #3624 (PR #3976) --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -32,6 +32,7 @@ import requireSubprocessTimeout from './eslint-rules/require-subprocess-timeout.
|
||||
import noExternalRequireInBin from './eslint-rules/no-external-require-in-bin.cjs';
|
||||
import noPrivateBinaryResolution from './eslint-rules/no-private-binary-resolution.cjs';
|
||||
import requireRegisteredExit from './eslint-rules/require-registered-exit.cjs';
|
||||
import noExactCaseEnvAccess from './eslint-rules/no-exact-case-env-access.cjs';
|
||||
|
||||
const localPlugin = {
|
||||
rules: {
|
||||
@@ -58,6 +59,7 @@ const localPlugin = {
|
||||
'no-external-require-in-bin': noExternalRequireInBin,
|
||||
'no-private-binary-resolution': noPrivateBinaryResolution,
|
||||
'require-registered-exit': requireRegisteredExit,
|
||||
'no-exact-case-env-access': noExactCaseEnvAccess,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -424,6 +426,9 @@ export default tseslint.config(
|
||||
// eslint-ignored (ADR-457), so a rule registered only on the emitted
|
||||
// surface never sees the real .cts sources (#3496).
|
||||
'local/require-registered-exit': 'error',
|
||||
// #3624 (epic #3411 Phase 4): flag an exact-case env-var read off a
|
||||
// non-process.env receiver. See CONTEXT.md DEFECT.WINDOWS-EXACT-CASE-ENV-ACCESS.
|
||||
'local/no-exact-case-env-access': 'error',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -544,6 +549,8 @@ export default tseslint.config(
|
||||
'local/no-private-binary-resolution': 'error',
|
||||
// #3910 (epic #3889 Phase 6): see the src/**/*.cts block above for detail.
|
||||
'local/require-registered-exit': 'error',
|
||||
// #3624: see the src/**/*.cts block above for detail.
|
||||
'local/no-exact-case-env-access': 'error',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -573,6 +580,8 @@ export default tseslint.config(
|
||||
'local/no-private-binary-resolution': 'error',
|
||||
// #3910 (epic #3889 Phase 6): see the src/**/*.cts block above for detail.
|
||||
'local/require-registered-exit': 'error',
|
||||
// #3624: see the src/**/*.cts block above for detail.
|
||||
'local/no-exact-case-env-access': 'error',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -599,6 +608,8 @@ export default tseslint.config(
|
||||
// (n/no-process-exit: 'off') is now dead — see the src/**/*.cts block
|
||||
// above for detail on the rule itself.
|
||||
'local/require-registered-exit': 'error',
|
||||
// #3624: see the src/**/*.cts block above for detail.
|
||||
'local/no-exact-case-env-access': 'error',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user