diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index a8b37325b..73af008ce 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1099,7 +1099,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_); @@ -1125,7 +1125,7 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial if (!e) e = parseExprFromFile(checkSourcePath(resolvedPath)); - cacheFile(path, resolvedPath, e, v, mustBeTrivial); + cacheFile(path, resolvedPath, e, v); } @@ -1140,8 +1140,8 @@ void EvalState::cacheFile( const SourcePath & path, const SourcePath & resolvedPath, Expr * e, - Value & v, - bool mustBeTrivial) + Value & v +) { fileParseCache[resolvedPath] = e; @@ -1154,12 +1154,6 @@ void EvalState::cacheFile( e->getPos() ? std::make_shared(positions[e->getPos()]) : nullptr, "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) { addErrorTrace(e, "while evaluating the file '%1%':", resolvedPath.to_string()); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 411364d9f..04f8cc2c9 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -352,11 +352,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); /** * Like `evalFile`, but with an already parsed expression. @@ -365,8 +363,8 @@ public: const SourcePath & path, const SourcePath & resolvedPath, Expr * e, - Value & v, - bool mustBeTrivial = false); + Value & v + ); void resetFileCache(); diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index e13d1cb93..e29e596fb 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -232,9 +232,13 @@ static Flake getFlake( .sourceInfo = std::make_shared(std::move(sourceInfo)) }; - // NOTE evalFile forces vInfo to be an attrset because mustBeTrivial is true. Value vInfo; - state.evalFile(CanonPath(flakeFile), vInfo, true); // FIXME: symlink attack + state.evalFile(CanonPath(flakeFile), vInfo); // FIXME: symlink attack + if (vInfo.type() != nAttrs) { + state.error( + "file '%s' must be an attribute set, but is %s", flakeFile, showType(vInfo) + ).debugThrow(); + } if (auto description = vInfo.attrs->get(state.sDescription)) { expectType(state, nString, *description->value, description->pos);