MCPcopy Index your code
hub / github.com/codeaashu/claude-code / realpathDeepestExisting

Function realpathDeepestExisting

src/memdir/teamMemPaths.ts:109–171  ·  view source on GitHub ↗

* Resolve symlinks for the deepest existing ancestor of a path. * The target file may not exist yet (we may be about to create it), so we * walk up the directory tree until realpath() succeeds, then rejoin the * non-existing tail onto the resolved ancestor. * * SECURITY (PSR M22186): path.resol

(absolutePath: string)

Source from the content-addressed store, hash-verified

107 *
108 */
109async function realpathDeepestExisting(absolutePath: string): Promise<string> {
110 const tail: string[] = []
111 let current = absolutePath
112 // Walk up until realpath succeeds. ENOENT means this segment doesn't exist
113 // yet; pop it onto the tail and try the parent. ENOTDIR means a non-directory
114 // component sits in the middle of the path; pop and retry so we can realpath
115 // the ancestor to detect symlink escapes.
116 // Loop terminates when we reach the filesystem root (dirname('/') === '/').
117 for (
118 let parent = dirname(current);
119 current !== parent;
120 parent = dirname(current)
121 ) {
122 try {
123 const realCurrent = await realpath(current)
124 // Rejoin the non-existing tail in reverse order (deepest popped first)
125 return tail.length === 0
126 ? realCurrent
127 : join(realCurrent, ...tail.reverse())
128 } catch (e: unknown) {
129 const code = getErrnoCode(e)
130 if (code === 'ENOENT') {
131 // Could be truly non-existent (safe to walk up) OR a dangling symlink
132 // whose target doesn't exist. Dangling symlinks are an attack vector:
133 // writeFile would follow the link and create the target outside teamDir.
134 // lstat distinguishes: it succeeds for dangling symlinks (the link entry
135 // itself exists), fails with ENOENT for truly non-existent paths.
136 try {
137 const st = await lstat(current)
138 if (st.isSymbolicLink()) {
139 throw new PathTraversalError(
140 `Dangling symlink detected (target does not exist): "${current}"`,
141 )
142 }
143 // lstat succeeded but isn't a symlink — ENOENT from realpath was
144 // caused by a dangling symlink in an ancestor. Walk up to find it.
145 } catch (lstatErr: unknown) {
146 if (lstatErr instanceof PathTraversalError) {
147 throw lstatErr
148 }
149 // lstat also failed (truly non-existent or inaccessible) — safe to walk up.
150 }
151 } else if (code === 'ELOOP') {
152 // Symlink loop — corrupted or malicious filesystem state.
153 throw new PathTraversalError(
154 `Symlink loop detected in path: "${current}"`,
155 )
156 } else if (code !== 'ENOTDIR' && code !== 'ENAMETOOLONG') {
157 // EACCES, EIO, etc. — cannot verify containment. Fail closed by wrapping
158 // as PathTraversalError so the caller can skip this entry gracefully
159 // instead of aborting the entire batch.
160 throw new PathTraversalError(
161 `Cannot verify path containment (${code}): "${current}"`,
162 )
163 }
164 tail.push(current.slice(parent.length + sep.length))
165 current = parent
166 }

Callers 2

validateTeamMemWritePathFunction · 0.85
validateTeamMemKeyFunction · 0.85

Calls 2

getErrnoCodeFunction · 0.85
pushMethod · 0.45

Tested by

no test coverage detected