fix(permissions): normalize Windows absolute file-rule matching (#973)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -272,6 +272,53 @@ test("Allow exact Bash command", () => {
|
||||
expect(result2.decision).toBe("ask"); // Doesn't match exact
|
||||
});
|
||||
|
||||
test("Issue #969: legacy Windows Edit allow rule matches memory project file", () => {
|
||||
const permissions: PermissionRules = {
|
||||
allow: [
|
||||
"Edit(/C:\\Users\\Aaron\\.letta\\agents\\agent-7dcc\\memory\\system\\project/**)",
|
||||
],
|
||||
deny: [],
|
||||
ask: [],
|
||||
};
|
||||
|
||||
const result = checkPermission(
|
||||
"Edit",
|
||||
{
|
||||
file_path:
|
||||
"C:\\Users\\Aaron\\.letta\\agents\\agent-7dcc\\memory\\system\\project\\tech_stack.md",
|
||||
},
|
||||
permissions,
|
||||
"C:\\Users\\Aaron\\repo",
|
||||
);
|
||||
|
||||
expect(result.decision).toBe("allow");
|
||||
expect(result.matchedRule).toBe(
|
||||
"Edit(/C:\\Users\\Aaron\\.letta\\agents\\agent-7dcc\\memory\\system\\project/**)",
|
||||
);
|
||||
});
|
||||
|
||||
test("Issue #969 guardrail: Windows legacy Edit rule does not over-match sibling subtree", () => {
|
||||
const permissions: PermissionRules = {
|
||||
allow: [
|
||||
"Edit(/C:\\Users\\Aaron\\.letta\\agents\\agent-7dcc\\memory\\system\\project/**)",
|
||||
],
|
||||
deny: [],
|
||||
ask: [],
|
||||
};
|
||||
|
||||
const result = checkPermission(
|
||||
"Edit",
|
||||
{
|
||||
file_path:
|
||||
"C:\\Users\\Aaron\\.letta\\agents\\agent-7dcc\\memory\\system\\other\\x.md",
|
||||
},
|
||||
permissions,
|
||||
"C:\\Users\\Aaron\\repo",
|
||||
);
|
||||
|
||||
expect(result.decision).toBe("ask");
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Ask Rule Tests
|
||||
// ============================================================================
|
||||
|
||||
@@ -349,3 +349,73 @@ test("File pattern: Windows absolute path in working directory", () => {
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("File pattern: Windows absolute variants are equivalent", () => {
|
||||
const query =
|
||||
"Edit(C:\\Users\\Aaron\\.letta\\agents\\agent-1\\memory\\system\\project\\tech_stack.md)";
|
||||
const workingDir = "C:\\Users\\Aaron\\repo";
|
||||
|
||||
expect(
|
||||
matchesFilePattern(
|
||||
query,
|
||||
"Edit(/C:/Users/Aaron/.letta/agents/agent-1/memory/system/project/**)",
|
||||
workingDir,
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
expect(
|
||||
matchesFilePattern(
|
||||
query,
|
||||
"Edit(//C:/Users/Aaron/.letta/agents/agent-1/memory/system/project/**)",
|
||||
workingDir,
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
expect(
|
||||
matchesFilePattern(
|
||||
query,
|
||||
"Edit(C:/Users/Aaron/.letta/agents/agent-1/memory/system/project/**)",
|
||||
workingDir,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("File pattern: Windows drive-letter matching is case-insensitive", () => {
|
||||
const query = "Edit(c:\\users\\aaron\\repo\\src\\file.ts)";
|
||||
const workingDir = "C:\\Users\\Aaron\\repo";
|
||||
|
||||
expect(
|
||||
matchesFilePattern(query, "Edit(C:/Users/Aaron/repo/src/**)", workingDir),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("File pattern: UNC absolute path matches normalized UNC pattern", () => {
|
||||
const query = "Edit(\\\\server\\share\\folder\\file.md)";
|
||||
const workingDir = "C:\\Users\\Aaron\\repo";
|
||||
|
||||
expect(
|
||||
matchesFilePattern(query, "Edit(//server/share/folder/**)", workingDir),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("File pattern: extended Windows drive path matches canonical drive pattern", () => {
|
||||
const query = String.raw`Edit(\\?\C:\Users\Aaron\folder\file.md)`;
|
||||
const workingDir = String.raw`C:\Users\Aaron\repo`;
|
||||
|
||||
expect(
|
||||
matchesFilePattern(query, "Edit(C:/Users/Aaron/folder/**)", workingDir),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("File pattern: extended UNC pattern matches UNC query path", () => {
|
||||
const query = String.raw`Edit(\\server\share\folder\file.md)`;
|
||||
const workingDir = String.raw`C:\Users\Aaron\repo`;
|
||||
|
||||
expect(
|
||||
matchesFilePattern(
|
||||
query,
|
||||
"Edit(//?/UNC/server/share/folder/**)",
|
||||
workingDir,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user