Disallow unsafe type assertions (#18688)

This commit is contained in:
Christian Gunderman
2026-02-10 00:10:15 +00:00
committed by GitHub
parent bce1caefd0
commit fd65416a2f
188 changed files with 592 additions and 47 deletions
+2
View File
@@ -382,6 +382,7 @@ export function createPolicyUpdater(
const fileContent = await fs.readFile(policyFile, 'utf-8');
existingData = toml.parse(fileContent) as { rule?: TomlRule[] };
} catch (error) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
debugLogger.warn(
`Failed to parse ${policyFile}, overwriting with new policy.`,
@@ -424,6 +425,7 @@ export function createPolicyUpdater(
// Serialize back to TOML
// @iarna/toml stringify might not produce beautiful output but it handles escaping correctly
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const newContent = toml.stringify(existingData as toml.JsonMap);
// Atomic write: write to tmp then rename
@@ -312,6 +312,7 @@ export class PolicyEngine {
if (toolName && SHELL_TOOL_NAMES.includes(toolName)) {
isShellCommand = true;
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const args = toolCall.args as { command?: string; dir_path?: string };
command = args?.command;
shellDirPath = args?.dir_path;
@@ -111,6 +111,7 @@ export function stableStringify(obj: unknown): string {
const pairs: string[] = [];
for (const key of sortedKeys) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const value = (currentObj as Record<string, unknown>)[key];
// Skip undefined and function values in objects (per JSON spec)
if (value !== undefined && typeof value !== 'function') {
+6
View File
@@ -234,6 +234,7 @@ export async function loadPoliciesFromToml(
.filter((entry) => entry.isFile() && entry.name.endsWith('.toml'))
.map((entry) => entry.name);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const error = e as NodeJS.ErrnoException;
if (error.code === 'ENOENT') {
// Directory doesn't exist, skip it (not an error)
@@ -262,6 +263,7 @@ export async function loadPoliciesFromToml(
try {
parsed = toml.parse(fileContent);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const error = e as Error;
errors.push({
filePath,
@@ -356,6 +358,7 @@ export async function loadPoliciesFromToml(
try {
policyRule.argsPattern = new RegExp(argsPattern);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const error = e as Error;
errors.push({
filePath,
@@ -411,6 +414,7 @@ export async function loadPoliciesFromToml(
const safetyCheckerRule: SafetyCheckerRule = {
toolName: effectiveToolName,
priority: checker.priority,
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
checker: checker.checker as SafetyCheckerConfig,
modes: checker.modes,
};
@@ -419,6 +423,7 @@ export async function loadPoliciesFromToml(
try {
safetyCheckerRule.argsPattern = new RegExp(argsPattern);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const error = e as Error;
errors.push({
filePath,
@@ -440,6 +445,7 @@ export async function loadPoliciesFromToml(
checkers.push(...parsedCheckers);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const error = e as NodeJS.ErrnoException;
// Catch-all for unexpected errors
if (error.code !== 'ENOENT') {
+2
View File
@@ -35,8 +35,10 @@ export function getHookSource(input: Record<string, unknown>): HookSource {
const source = input['hook_source'];
if (
typeof source === 'string' &&
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
VALID_HOOK_SOURCES.includes(source as HookSource)
) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
return source as HookSource;
}
return 'project';