mirror of
https://github.com/NixOS/nix
synced 2025-06-29 06:21:14 +02:00
Restore builtins.pathExists
behavior on broken symlinks
Commit83c067c0fa
changed `builtins.pathExists` to resolve symlinks before checking for existence. Consequently, if the path refers to a symlink itself, existence of the target of the symlink (instead of the symlink itself) was checked. Restore the previous behavior by skipping symlink resolution in the last component. (cherry picked from commit89e21ab4bd
)
This commit is contained in:
parent
982d07d009
commit
0571e6e9b4
5 changed files with 46 additions and 19 deletions
|
@ -118,7 +118,7 @@ StringMap EvalState::realiseContext(const NixStringContext & context)
|
|||
return res;
|
||||
}
|
||||
|
||||
static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, bool resolveSymlinks = true)
|
||||
static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, std::optional<SymlinkResolution> resolveSymlinks = SymlinkResolution::Full)
|
||||
{
|
||||
NixStringContext context;
|
||||
|
||||
|
@ -130,7 +130,7 @@ static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, bo
|
|||
auto realPath = state.toRealPath(rewriteStrings(path.path.abs(), rewrites), context);
|
||||
path = {path.accessor, CanonPath(realPath)};
|
||||
}
|
||||
return resolveSymlinks ? path.resolveSymlinks() : path;
|
||||
return resolveSymlinks ? path.resolveSymlinks(*resolveSymlinks) : path;
|
||||
} catch (Error & e) {
|
||||
e.addTrace(state.positions[pos], "while realising the context of path '%s'", path);
|
||||
throw;
|
||||
|
@ -170,7 +170,7 @@ static void mkOutputString(
|
|||
argument. */
|
||||
static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * vScope, Value & v)
|
||||
{
|
||||
auto path = realisePath(state, pos, vPath, false);
|
||||
auto path = realisePath(state, pos, vPath, std::nullopt);
|
||||
auto path2 = path.path.abs();
|
||||
|
||||
// FIXME
|
||||
|
@ -1534,13 +1534,16 @@ static void prim_pathExists(EvalState & state, const PosIdx pos, Value * * args,
|
|||
try {
|
||||
auto & arg = *args[0];
|
||||
|
||||
auto path = realisePath(state, pos, arg);
|
||||
|
||||
/* SourcePath doesn't know about trailing slash. */
|
||||
state.forceValue(arg, pos);
|
||||
auto mustBeDir = arg.type() == nString
|
||||
&& (arg.string_view().ends_with("/")
|
||||
|| arg.string_view().ends_with("/."));
|
||||
|
||||
auto symlinkResolution =
|
||||
mustBeDir ? SymlinkResolution::Full : SymlinkResolution::Ancestors;
|
||||
auto path = realisePath(state, pos, arg, symlinkResolution);
|
||||
|
||||
auto st = path.maybeLstat();
|
||||
auto exists = st && (!mustBeDir || st->type == SourceAccessor::tDirectory);
|
||||
v.mkBool(exists);
|
||||
|
@ -1777,7 +1780,7 @@ static std::string_view fileTypeToString(InputAccessor::Type type)
|
|||
|
||||
static void prim_readFileType(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
auto path = realisePath(state, pos, *args[0], false);
|
||||
auto path = realisePath(state, pos, *args[0], std::nullopt);
|
||||
/* Retrieve the directory entry type and stringize it. */
|
||||
v.mkString(fileTypeToString(path.lstat().type));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue