mirror of
https://github.com/NixOS/nix
synced 2025-06-25 19:01:16 +02:00
parent
8abff3cf05
commit
0213f22650
3 changed files with 44 additions and 0 deletions
|
@ -765,4 +765,19 @@ bool isExecutableFileAmbient(const fs::path & exe) {
|
||||||
) == 0;
|
) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::filesystem::path makeParentCanonical(const std::filesystem::path & rawPath)
|
||||||
|
{
|
||||||
|
std::filesystem::path path(absPath(rawPath));;
|
||||||
|
try {
|
||||||
|
auto parent = path.parent_path();
|
||||||
|
if (parent == path) {
|
||||||
|
// `path` is a root directory => trivially canonical
|
||||||
|
return parent;
|
||||||
}
|
}
|
||||||
|
return std::filesystem::canonical(parent) / path.filename();
|
||||||
|
} catch (fs::filesystem_error & e) {
|
||||||
|
throw SysError("canonicalising parent path of '%1%'", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nix
|
||||||
|
|
|
@ -143,6 +143,23 @@ inline bool symlink_exists(const std::filesystem::path & path) {
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Canonicalize a path except for the last component.
|
||||||
|
*
|
||||||
|
* This is useful for getting the canonical location of a symlink.
|
||||||
|
*
|
||||||
|
* Consider the case where `foo/l` is a symlink. `canonical("foo/l")` will
|
||||||
|
* resolve the symlink `l` to its target.
|
||||||
|
* `makeParentCanonical("foo/l")` will not resolve the symlink `l` to its target,
|
||||||
|
* but does ensure that the returned parent part of the path, `foo` is resolved
|
||||||
|
* to `canonical("foo")`, and can therefore be retrieved without traversing any
|
||||||
|
* symlinks.
|
||||||
|
*
|
||||||
|
* If a relative path is passed, it will be made absolute, so that the parent
|
||||||
|
* can always be canonicalized.
|
||||||
|
*/
|
||||||
|
std::filesystem::path makeParentCanonical(const std::filesystem::path & path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A version of pathExists that returns false on a permission error.
|
* A version of pathExists that returns false on a permission error.
|
||||||
* Useful for inferring default paths across directories that might not
|
* Useful for inferring default paths across directories that might not
|
||||||
|
|
|
@ -50,6 +50,18 @@ struct PosixSourceAccessor : virtual SourceAccessor
|
||||||
* possible, (e.g. on Windows it could scoped to a drive like
|
* possible, (e.g. on Windows it could scoped to a drive like
|
||||||
* `C:\`). This allows more `..` parent accessing to work.
|
* `C:\`). This allows more `..` parent accessing to work.
|
||||||
*
|
*
|
||||||
|
* @note When `path` is trusted user input, canonicalize it using
|
||||||
|
* `std::filesystem::canonical`, `makeParentCanonical`, `std::filesystem::weakly_canonical`, etc,
|
||||||
|
* as appropriate for the use case. At least weak canonicalization is
|
||||||
|
* required for the `SourcePath` to do anything useful at the location it
|
||||||
|
* points to.
|
||||||
|
*
|
||||||
|
* @note A canonicalizing behavior is not built in `createAtRoot` so that
|
||||||
|
* callers do not accidentally introduce symlink-related security vulnerabilities.
|
||||||
|
* Furthermore, `createAtRoot` does not know whether the file pointed to by
|
||||||
|
* `path` should be resolved if it is itself a symlink. In other words,
|
||||||
|
* `createAtRoot` can not decide between aforementioned `canonical`, `makeParentCanonical`, etc. for its callers.
|
||||||
|
*
|
||||||
* See
|
* See
|
||||||
* [`std::filesystem::path::root_path`](https://en.cppreference.com/w/cpp/filesystem/path/root_path)
|
* [`std::filesystem::path::root_path`](https://en.cppreference.com/w/cpp/filesystem/path/root_path)
|
||||||
* and
|
* and
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue