mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-27 19:56:56 -07:00
Revert "fix(core-tools): resolve defensive path resolution for at-reference files" (#27992)
This commit is contained in:
@@ -8,7 +8,6 @@ import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import type { Config } from '../config/config.js';
|
||||
import { bfsFileSearchSync } from './bfsFileSearch.js';
|
||||
import { resolveDefensiveToolPath } from './paths.js';
|
||||
|
||||
type SuccessfulPathCorrection = {
|
||||
success: true;
|
||||
@@ -35,13 +34,8 @@ export function correctPath(
|
||||
filePath: string,
|
||||
config: Config,
|
||||
): PathCorrectionResult {
|
||||
const sanitizedPath = resolveDefensiveToolPath(
|
||||
filePath,
|
||||
config.getTargetDir(),
|
||||
);
|
||||
|
||||
// Check for direct path relative to the primary target directory.
|
||||
const directPath = path.join(config.getTargetDir(), sanitizedPath);
|
||||
const directPath = path.join(config.getTargetDir(), filePath);
|
||||
if (fs.existsSync(directPath)) {
|
||||
return { success: true, correctedPath: directPath };
|
||||
}
|
||||
@@ -49,8 +43,8 @@ export function correctPath(
|
||||
// If not found directly, search across all workspace directories for ambiguous matches.
|
||||
const workspaceContext = config.getWorkspaceContext();
|
||||
const searchPaths = workspaceContext.getDirectories();
|
||||
const basename = path.basename(sanitizedPath);
|
||||
const normalizedTarget = sanitizedPath.replace(/\\/g, '/');
|
||||
const basename = path.basename(filePath);
|
||||
const normalizedTarget = filePath.replace(/\\/g, '/');
|
||||
|
||||
// Normalize path for matching and check if it ends with the provided relative path
|
||||
const foundFiles = searchPaths
|
||||
|
||||
@@ -572,59 +572,3 @@ export function isTrustedSystemPath(filePath: string): boolean {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defensively resolves and sanitizes a file path generated by the LLM,
|
||||
* stripping user-facing reference prefixes if necessary.
|
||||
*/
|
||||
export function resolveDefensiveToolPath(
|
||||
filePath: string,
|
||||
targetDir: string,
|
||||
): string {
|
||||
if (filePath.includes('\0')) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
try {
|
||||
const literalPath = path.resolve(targetDir, filePath);
|
||||
|
||||
// If the file literally exists on disk as-is, return the resolved literal path immediately
|
||||
if (fs.existsSync(literalPath)) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
// If the model supplied a leading @ prefix and the literal path doesn't exist:
|
||||
if (filePath.startsWith('@') && filePath.length > 1) {
|
||||
if (filePath.startsWith('@/') || filePath.startsWith('@\\')) {
|
||||
return filePath.substring(1).replace(/^[\\/]+/, '');
|
||||
}
|
||||
|
||||
const strippedPath = filePath.substring(1).replace(/^[\\/]+/, '');
|
||||
|
||||
// Check if a literal directory/file starting with '@' exists for the first segment.
|
||||
// If it does, we should preserve the '@' prefix.
|
||||
const parts = strippedPath.split(/[\\/]/);
|
||||
const firstSegment = parts[0];
|
||||
if (firstSegment) {
|
||||
const literalFirstSegment = path.resolve(targetDir, '@' + firstSegment);
|
||||
if (fs.existsSync(literalFirstSegment)) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
// Only strip the '@' prefix if the stripped path's first segment actually exists
|
||||
const strippedFirstSegment = path.resolve(targetDir, firstSegment);
|
||||
if (fs.existsSync(strippedFirstSegment)) {
|
||||
return strippedPath;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, preserve the '@' prefix to allow creating new files/directories starting with '@'
|
||||
return filePath;
|
||||
}
|
||||
} catch {
|
||||
// Fallback to original path if any filesystem or resolution error occurs
|
||||
}
|
||||
|
||||
// Fallback: return the original path
|
||||
return filePath;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user