fix: enforce folder trust for workspace settings, skills, and context (#17596)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Gal Zahavi
2026-02-03 14:53:31 -08:00
committed by GitHub
parent d63c34b6e1
commit 71f46f1160
18 changed files with 1310 additions and 788 deletions
@@ -40,6 +40,7 @@ describe('ContextManager', () => {
getMcpClientManager: vi.fn().mockReturnValue({
getMcpInstructions: vi.fn().mockReturnValue('MCP Instructions'),
}),
isTrustedFolder: vi.fn().mockReturnValue(true),
} as unknown as Config;
contextManager = new ContextManager(mockConfig);
@@ -112,6 +113,24 @@ describe('ContextManager', () => {
fileCount: 2,
});
});
it('should not load environment memory if folder is not trusted', async () => {
vi.mocked(mockConfig.isTrustedFolder).mockReturnValue(false);
const mockGlobalResult = {
files: [
{ path: '/home/user/.gemini/GEMINI.md', content: 'Global Content' },
],
};
vi.mocked(memoryDiscovery.loadGlobalMemory).mockResolvedValue(
mockGlobalResult,
);
await contextManager.refresh();
expect(memoryDiscovery.loadEnvironmentMemory).not.toHaveBeenCalled();
expect(contextManager.getEnvironmentMemory()).toBe('');
expect(contextManager.getGlobalMemory()).toContain('Global Content');
});
});
describe('discoverContext', () => {
@@ -150,5 +169,16 @@ describe('ContextManager', () => {
expect(result).toBe('');
});
it('should return empty string if folder is not trusted', async () => {
vi.mocked(mockConfig.isTrustedFolder).mockReturnValue(false);
const result = await contextManager.discoverContext('/app/src/file.ts', [
'/app',
]);
expect(memoryDiscovery.loadJitSubdirectoryMemory).not.toHaveBeenCalled();
expect(result).toBe('');
});
});
});
+8 -3
View File
@@ -43,6 +43,10 @@ export class ContextManager {
}
private async loadEnvironmentMemory(): Promise<void> {
if (!this.config.isTrustedFolder()) {
this.environmentMemory = '';
return;
}
const result = await loadEnvironmentMemory(
[...this.config.getWorkspaceContext().getDirectories()],
this.config.getExtensionLoader(),
@@ -68,6 +72,9 @@ export class ContextManager {
accessedPath: string,
trustedRoots: string[],
): Promise<string> {
if (!this.config.isTrustedFolder()) {
return '';
}
const result = await loadJitSubdirectoryMemory(
accessedPath,
trustedRoots,
@@ -101,9 +108,7 @@ export class ContextManager {
}
private markAsLoaded(paths: string[]): void {
for (const p of paths) {
this.loadedPaths.add(p);
}
paths.forEach((p) => this.loadedPaths.add(p));
}
getLoadedPaths(): ReadonlySet<string> {