mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-19 18:40:57 -07:00
feat(windows-sandbox): address final async review findings and fix eslint
This commit is contained in:
@@ -11,8 +11,9 @@ import type {
|
||||
SandboxRequest,
|
||||
SandboxedCommand,
|
||||
} from './sandboxManager.js';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { spawn, type ChildProcess } from 'node:child_process';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import type { Writable } from 'node:stream';
|
||||
|
||||
vi.mock('node:child_process', () => ({
|
||||
spawn: vi.fn(),
|
||||
@@ -40,10 +41,11 @@ describe('SandboxedFileSystemService', () => {
|
||||
});
|
||||
|
||||
it('should read a file through the sandbox', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mockChild = new EventEmitter() as any;
|
||||
mockChild.stdout = new EventEmitter();
|
||||
mockChild.stderr = new EventEmitter();
|
||||
const mockChild = new EventEmitter() as unknown as ChildProcess;
|
||||
Object.assign(mockChild, {
|
||||
stdout: new EventEmitter(),
|
||||
stderr: new EventEmitter(),
|
||||
});
|
||||
|
||||
vi.mocked(spawn).mockReturnValue(mockChild);
|
||||
|
||||
@@ -65,13 +67,14 @@ describe('SandboxedFileSystemService', () => {
|
||||
});
|
||||
|
||||
it('should write a file through the sandbox', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mockChild = new EventEmitter() as any;
|
||||
mockChild.stdin = {
|
||||
write: vi.fn(),
|
||||
end: vi.fn(),
|
||||
};
|
||||
mockChild.stderr = new EventEmitter();
|
||||
const mockChild = new EventEmitter() as unknown as ChildProcess;
|
||||
Object.assign(mockChild, {
|
||||
stdin: {
|
||||
write: vi.fn(),
|
||||
end: vi.fn(),
|
||||
} as unknown as Writable,
|
||||
stderr: new EventEmitter(),
|
||||
});
|
||||
|
||||
vi.mocked(spawn).mockReturnValue(mockChild);
|
||||
|
||||
@@ -92,10 +95,11 @@ describe('SandboxedFileSystemService', () => {
|
||||
});
|
||||
|
||||
it('should reject if sandbox command fails', async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mockChild = new EventEmitter() as any;
|
||||
mockChild.stdout = new EventEmitter();
|
||||
mockChild.stderr = new EventEmitter();
|
||||
const mockChild = new EventEmitter() as unknown as ChildProcess;
|
||||
Object.assign(mockChild, {
|
||||
stdout: new EventEmitter(),
|
||||
stderr: new EventEmitter(),
|
||||
});
|
||||
|
||||
vi.mocked(spawn).mockReturnValue(mockChild);
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
sanitizeEnvironment,
|
||||
type EnvironmentSanitizationConfig,
|
||||
} from './environmentSanitization.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -44,42 +45,49 @@ export class WindowsSandboxManager implements SandboxManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(this.helperPath)) {
|
||||
// If the exe doesn't exist, we try to compile it from the .cs file
|
||||
const sourcePath = this.helperPath.replace(/\.exe$/, '.cs');
|
||||
if (fs.existsSync(sourcePath)) {
|
||||
const systemRoot = process.env['SystemRoot'] || 'C:\\Windows';
|
||||
const cscPaths = [
|
||||
'csc.exe', // Try in PATH first
|
||||
path.join(
|
||||
systemRoot,
|
||||
'Microsoft.NET',
|
||||
'Framework64',
|
||||
'v4.0.30319',
|
||||
'csc.exe',
|
||||
),
|
||||
path.join(
|
||||
systemRoot,
|
||||
'Microsoft.NET',
|
||||
'Framework',
|
||||
'v4.0.30319',
|
||||
'csc.exe',
|
||||
),
|
||||
];
|
||||
try {
|
||||
if (!fs.existsSync(this.helperPath)) {
|
||||
// If the exe doesn't exist, we try to compile it from the .cs file
|
||||
const sourcePath = this.helperPath.replace(/\.exe$/, '.cs');
|
||||
if (fs.existsSync(sourcePath)) {
|
||||
const systemRoot = process.env['SystemRoot'] || 'C:\\Windows';
|
||||
const cscPaths = [
|
||||
'csc.exe', // Try in PATH first
|
||||
path.join(
|
||||
systemRoot,
|
||||
'Microsoft.NET',
|
||||
'Framework64',
|
||||
'v4.0.30319',
|
||||
'csc.exe',
|
||||
),
|
||||
path.join(
|
||||
systemRoot,
|
||||
'Microsoft.NET',
|
||||
'Framework',
|
||||
'v4.0.30319',
|
||||
'csc.exe',
|
||||
),
|
||||
];
|
||||
|
||||
for (const csc of cscPaths) {
|
||||
const result = spawnSync(
|
||||
csc,
|
||||
['/out:' + this.helperPath, sourcePath],
|
||||
{
|
||||
stdio: 'ignore',
|
||||
},
|
||||
);
|
||||
if (result.status === 0) {
|
||||
break;
|
||||
for (const csc of cscPaths) {
|
||||
const result = spawnSync(
|
||||
csc,
|
||||
['/out:' + this.helperPath, sourcePath],
|
||||
{
|
||||
stdio: 'ignore',
|
||||
},
|
||||
);
|
||||
if (result.status === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugLogger.log(
|
||||
'WindowsSandboxManager: Failed to initialize sandbox helper:',
|
||||
e,
|
||||
);
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
@@ -171,8 +179,12 @@ export class WindowsSandboxManager implements SandboxManager {
|
||||
if (result.status === 0) {
|
||||
this.lowIntegrityCache.add(resolvedPath);
|
||||
}
|
||||
} catch (_e) {
|
||||
// Best effort
|
||||
} catch (e) {
|
||||
debugLogger.log(
|
||||
'WindowsSandboxManager: icacls failed for',
|
||||
resolvedPath,
|
||||
e,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user