fix(coding-agent): preserve encoded memory glob bases
This commit is contained in:
@@ -88,15 +88,13 @@ export function splitMemoryGlobPattern(input: string): MemoryGlobPattern {
|
||||
throw toMemoryValidationError(error);
|
||||
}
|
||||
|
||||
const decodedSegments = relativePath.split("/");
|
||||
const firstGlobIndex = decodedSegments.findIndex(segment =>
|
||||
["*", "?", "[", "{"].some(char => segment.includes(char)),
|
||||
);
|
||||
const rawSegments = rawPathname.replace(/^\//, "").split("/");
|
||||
const firstGlobIndex = rawSegments.findIndex(segment => ["*", "?", "[", "{"].some(char => segment.includes(char)));
|
||||
if (firstGlobIndex === -1) {
|
||||
throw new Error(`memory:// URL does not contain a glob pattern: ${input}`);
|
||||
}
|
||||
|
||||
const rawSegments = rawPathname.replace(/^\//, "").split("/");
|
||||
const decodedSegments = relativePath.split("/");
|
||||
const rawBasePath = rawSegments.slice(0, firstGlobIndex).join("/") || ".";
|
||||
return {
|
||||
baseUrl: `memory://${namespace}/${rawBasePath}`,
|
||||
|
||||
@@ -192,7 +192,9 @@ export class GlobTool implements AgentTool<typeof findSchema, GlobToolDetails> {
|
||||
if (!resource.sourcePath) {
|
||||
throw new ToolError(`Cannot find internal URL without a backing file: ${memoryGlob.baseUrl}`);
|
||||
}
|
||||
normalizedPatterns.push(path.join(resource.sourcePath, memoryGlob.globPattern));
|
||||
normalizedPatterns.push(
|
||||
path.join(resource.sourcePath.replace(/[*?[{]/g, "[$&]"), memoryGlob.globPattern),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const resource = await internalRouter.resolve(rawPattern, {
|
||||
|
||||
@@ -284,6 +284,21 @@ describe("MemoryProtocolHandler", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("resolves encoded literal glob characters before the wildcard boundary", async () => {
|
||||
await withMemoryFixture(async ({ cwd, memoryRoot }) => {
|
||||
const encodedLiteralDir = path.join(memoryRoot, "skills", "[demo]");
|
||||
await fs.mkdir(encodedLiteralDir, { recursive: true });
|
||||
await Bun.write(path.join(encodedLiteralDir, "SKILL.md"), "encoded literal directory");
|
||||
|
||||
const result = await createGlobTool(cwd).execute("memory-encoded-literal-glob", {
|
||||
path: "memory://root/skills/%5Bdemo%5D/*.md",
|
||||
});
|
||||
|
||||
expect(result.details?.files).toHaveLength(1);
|
||||
expect(result.details?.files?.[0]).toEndWith("/skills/[demo]/SKILL.md");
|
||||
});
|
||||
});
|
||||
|
||||
it.each(["memory://root/skills/**/../*.md", "memory://root/skills/**/%2e%2e/*.md"])(
|
||||
"rejects traversal in a memory glob suffix: %s",
|
||||
async pattern => {
|
||||
|
||||
Reference in New Issue
Block a user