diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index d6e72cc7e..cab7f6c46 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -904,7 +904,7 @@ Value * ExprPath::maybeThunk(EvalState & state, Env & env) } -void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial) +void EvalState::evalFile(const SourcePath & path_, Value & v) { auto path = checkSourcePath(path_); @@ -933,11 +933,6 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial "while evaluating the file '%1%':", resolvedPath.to_string()) : nullptr; - // Enforce that 'flake.nix' is a direct attrset, not a - // computation. - if (mustBeTrivial && - !(dynamic_cast(&e))) - error("file '%s' must be an attribute set", path).debugThrow(); eval(e, v); } catch (Error & e) { e.addTrace(nullptr, "while evaluating the file '%1%':", resolvedPath.to_string()); diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index 6dde9e1f7..06e8aee4e 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -401,11 +401,9 @@ public: Expr & parseStdin(); /** - * Evaluate an expression read from the given file to normal - * form. Optionally enforce that the top-level expression is - * trivial (i.e. doesn't require arbitrary computation). + * Evaluate an expression read from the given file to normal form. */ - void evalFile(const SourcePath & path, Value & v, bool mustBeTrivial = false); + void evalFile(const SourcePath & path, Value & v); void resetFileCache(); diff --git a/lix/libexpr/flake/flake.cc b/lix/libexpr/flake/flake.cc index c18252a90..81efa3329 100644 --- a/lix/libexpr/flake/flake.cc +++ b/lix/libexpr/flake/flake.cc @@ -241,9 +241,17 @@ static Flake getFlake( .sourceInfo = std::make_shared(std::move(sourceInfo)) }; - // NOTE evalFile forces vInfo to be an attrset because mustBeTrivial is true. + // FIXME: symlink attack + auto resolvedFlakeFile = resolveExprPath(state.checkSourcePath(CanonPath(flakeFile))); + Expr & flakeExpr = state.parseExprFromFile(state.checkSourcePath(resolvedFlakeFile)); + + // Enforce that 'flake.nix' is a direct attrset, not a computation. + if (!(dynamic_cast(&flakeExpr))) { + state.error("file '%s' must be an attribute set", resolvedFlakeFile).debugThrow(); + } + Value vInfo; - state.evalFile(CanonPath(flakeFile), vInfo, true); // FIXME: symlink attack + state.eval(flakeExpr, vInfo); if (auto description = vInfo.attrs->get(state.s.description)) { expectType(state, nString, *description->value, description->pos);