Fix path concatenation

This commit is contained in:
Eelco Dolstra 2022-05-12 14:48:25 +02:00
parent b6cf6e5553
commit 84c273c503
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
4 changed files with 34 additions and 25 deletions

View file

@ -1788,39 +1788,48 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
Value values[es->size()]; Value values[es->size()];
Value * vTmpP = values; Value * vTmpP = values;
InputAccessor * accessor = nullptr;
for (auto & [i_pos, i] : *es) { for (auto & [i_pos, i] : *es) {
Value & vTmp = *vTmpP++; Value * vTmp = vTmpP++;
i->eval(state, env, vTmp); i->eval(state, env, *vTmp);
if (vTmp->type() == nAttrs) {
auto j = vTmp->attrs->find(state.sOutPath);
if (j != vTmp->attrs->end())
vTmp = j->value;
}
/* If the first element is a path, then the result will also /* If the first element is a path, then the result will also
be a path, we don't copy anything (yet - that's done later, be a path, we don't copy anything (yet - that's done later,
since paths are copied when they are used in a derivation), since paths are copied when they are used in a derivation),
and none of the strings are allowed to have contexts. */ and none of the strings are allowed to have contexts. */
if (first) { if (first) {
firstType = vTmp.type(); firstType = vTmp->type();
if (vTmp->type() == nPath)
accessor = &vTmp->path().accessor;
} }
if (firstType == nInt) { if (firstType == nInt) {
if (vTmp.type() == nInt) { if (vTmp->type() == nInt) {
n += vTmp.integer; n += vTmp->integer;
} else if (vTmp.type() == nFloat) { } else if (vTmp->type() == nFloat) {
// Upgrade the type from int to float; // Upgrade the type from int to float;
firstType = nFloat; firstType = nFloat;
nf = n; nf = n;
nf += vTmp.fpoint; nf += vTmp->fpoint;
} else } else
state.throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp)); state.throwEvalError(i_pos, "cannot add %1% to an integer", showType(*vTmp));
} else if (firstType == nFloat) { } else if (firstType == nFloat) {
if (vTmp.type() == nInt) { if (vTmp->type() == nInt) {
nf += vTmp.integer; nf += vTmp->integer;
} else if (vTmp.type() == nFloat) { } else if (vTmp->type() == nFloat) {
nf += vTmp.fpoint; nf += vTmp->fpoint;
} else } else
state.throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp)); state.throwEvalError(i_pos, "cannot add %1% to a float", showType(*vTmp));
} else { } else {
if (s.empty()) s.reserve(es->size()); if (s.empty()) s.reserve(es->size());
auto part = state.coerceToString(i_pos, vTmp, context, false, firstType == nString); auto part = state.coerceToString(i_pos, *vTmp, context, false, firstType == nString);
sSize += part->size(); sSize += part->size();
s.emplace_back(std::move(part)); s.emplace_back(std::move(part));
} }
@ -1835,7 +1844,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
else if (firstType == nPath) { else if (firstType == nPath) {
if (!context.empty()) if (!context.empty())
state.throwEvalError(pos, "a string that refers to a store path cannot be appended to a path"); state.throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
v.mkPath({.accessor = *values[0]._path.accessor, .path = canonPath(str())}); v.mkPath({.accessor = *accessor, .path = canonPath(str())});
} else } else
v.mkStringMove(c_str(), context); v.mkStringMove(c_str(), context);
} }

View file

@ -24,12 +24,6 @@ void emitTreeAttrs(
auto attrs = state.buildBindings(8); auto attrs = state.buildBindings(8);
#if 0
auto storePath = state.store->printStorePath(tree.storePath);
attrs.alloc(state.sOutPath).mkString(storePath, {storePath});
#endif
attrs.alloc(state.sOutPath).mkPath(path); attrs.alloc(state.sOutPath).mkPath(path);
// FIXME: support arbitrary input attributes. // FIXME: support arbitrary input attributes.

View file

@ -401,8 +401,13 @@ struct GitInputScheme : InputScheme
if (repoInfo.submodules) if (repoInfo.submodules)
gitOpts.emplace_back("--recurse-submodules"); gitOpts.emplace_back("--recurse-submodules");
return tokenizeString<std::set<std::string>>( std::set<std::string> res;
runProgram("git", true, gitOpts), "\0"s);
for (auto & p : tokenizeString<std::set<std::string>>(
runProgram("git", true, gitOpts), "\0"s))
res.insert(canonPath("/" + p));
return res;
} }
std::string getDefaultRef(const RepoInfo & repoInfo) std::string getDefaultRef(const RepoInfo & repoInfo)

View file

@ -184,9 +184,10 @@ struct FSInputAccessorImpl : FSInputAccessor
if (allowedPaths) { if (allowedPaths) {
// FIXME: this can be done more efficiently. // FIXME: this can be done more efficiently.
Path p(absPath); auto p = (std::string) absPath.substr(root.size());
if (p == "") p = "/";
while (true) { while (true) {
if (allowedPaths->find((std::string) p) != allowedPaths->end()) if (allowedPaths->find(p) != allowedPaths->end())
break; break;
if (p == "/") if (p == "/")
return false; return false;