resolvePath is adapted from https://cs.opensource.google/go/go/+/go1.23.0:src/path/filepath/path.go;l=147 The (only) changes are on Lstat and ReadLink, which are fed the actual host path, that is computed by `res.pathOnHost`
(path string)
| 310 | // resolvePath is adapted from https://cs.opensource.google/go/go/+/go1.23.0:src/path/filepath/path.go;l=147 |
| 311 | // The (only) changes are on Lstat and ReadLink, which are fed the actual host path, that is computed by `res.pathOnHost` |
| 312 | func (res *resolver) resolvePath(path string) (string, error) { |
| 313 | volLen := volumeNameLen(path) |
| 314 | pathSeparator := string(os.PathSeparator) |
| 315 | |
| 316 | if volLen < len(path) && os.IsPathSeparator(path[volLen]) { |
| 317 | volLen++ |
| 318 | } |
| 319 | vol := path[:volLen] |
| 320 | dest := vol |
| 321 | linksWalked := 0 |
| 322 | //nolint:ineffassign |
| 323 | for start, end := volLen, volLen; start < len(path); start = end { |
| 324 | for start < len(path) && os.IsPathSeparator(path[start]) { |
| 325 | start++ |
| 326 | } |
| 327 | end = start |
| 328 | for end < len(path) && !os.IsPathSeparator(path[end]) { |
| 329 | end++ |
| 330 | } |
| 331 | |
| 332 | // On Windows, "." can be a symlink. |
| 333 | // We look it up, and use the value if it is absolute. |
| 334 | // If not, we just return ".". |
| 335 | //nolint:staticcheck |
| 336 | isWindowsDot := runtime.GOOS == "windows" && path[volumeNameLen(path):] == "." |
| 337 | |
| 338 | // The next path component is in path[start:end]. |
| 339 | if end == start { |
| 340 | // No more path components. |
| 341 | break |
| 342 | } else if path[start:end] == "." && !isWindowsDot { |
| 343 | // Ignore path component ".". |
| 344 | continue |
| 345 | } else if path[start:end] == ".." { |
| 346 | // Back up to previous component if possible. |
| 347 | // Note that volLen includes any leading slash. |
| 348 | |
| 349 | // Set r to the index of the last slash in dest, |
| 350 | // after the volume. |
| 351 | var r int |
| 352 | for r = len(dest) - 1; r >= volLen; r-- { |
| 353 | if os.IsPathSeparator(dest[r]) { |
| 354 | break |
| 355 | } |
| 356 | } |
| 357 | if r < volLen || dest[r+1:] == ".." { |
| 358 | // Either path has no slashes |
| 359 | // (it's empty or just "C:") |
| 360 | // or it ends in a ".." we had to keep. |
| 361 | // Either way, keep this "..". |
| 362 | if len(dest) > volLen { |
| 363 | dest += pathSeparator |
| 364 | } |
| 365 | dest += ".." |
| 366 | } else { |
| 367 | // Discard everything since the last slash. |
| 368 | dest = dest[:r] |
| 369 | } |
no test coverage detected