MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / validatePathWithinRoot

Function validatePathWithinRoot

src/utils.ts:128–163  ·  view source on GitHub ↗
(
  projectRoot: string,
  filePath: string,
  options?: { allowSymlinkEscape?: boolean }
)

Source from the content-addressed store, hash-verified

126 * escapes the root
127 */
128export function validatePathWithinRoot(
129 projectRoot: string,
130 filePath: string,
131 options?: { allowSymlinkEscape?: boolean }
132): string | null {
133 // 1. Lexical containment — cheap, catches `../` traversal. Applies even on
134 // the indexing read path: a crafted `../` escape is still rejected.
135 const resolved = lexicalPathWithinRoot(projectRoot, filePath);
136 if (resolved === null) {
137 return null;
138 }
139 const normalizedRoot = path.resolve(projectRoot);
140
141 // 2. Symlink-aware containment — resolve symlinks on both sides and re-check,
142 // so an in-repo symlink whose real target escapes the root is rejected.
143 // The indexing read path (allowSymlinkEscape) skips only this rejection so
144 // it stays consistent with the directory walk, which already followed the
145 // in-root symlink to enumerate these files (#935).
146 try {
147 const realRoot = fs.realpathSync(normalizedRoot);
148 const realResolved = fs.realpathSync(resolved);
149 if (options?.allowSymlinkEscape) {
150 return realResolved;
151 }
152 return isWithinDir(realResolved, realRoot) ? realResolved : null;
153 } catch (err) {
154 // ENOENT: the path doesn't exist yet (a file about to be written, or an
155 // index entry for a since-deleted file) — no symlink to follow, and the
156 // lexical check already passed, so allow the lexical path. Any other
157 // resolution failure (ELOOP, EACCES, …) is treated as unsafe → reject.
158 if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
159 return resolved;
160 }
161 return null;
162 }
163}
164
165/**
166 * Validate that a path is a safe project root directory.

Callers 15

buildDetectionContextMethod · 0.90
indexAllMethod · 0.90
indexFileMethod · 0.90
indexFileWithContentMethod · 0.90
extractNodeCodeMethod · 0.90
pathIsProjectFileFunction · 0.90
isFileStaleOnDiskMethod · 0.90
whenLabelMethod · 0.90
handleExploreMethod · 0.90
handleFileViewMethod · 0.90
validateAnswerFilesFunction · 0.90

Calls 3

lexicalPathWithinRootFunction · 0.85
isWithinDirFunction · 0.85
resolveMethod · 0.65

Tested by

no test coverage detected