* Don't allow derivations with fixed and non-fixed outputs.

This commit is contained in:
Eelco Dolstra 2011-07-20 18:26:00 +00:00
parent b2027f70d9
commit c8606664ab
1 changed files with 40 additions and 45 deletions

View File

@ -394,23 +394,11 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
throw EvalError(format("derivation names are not allowed to end in `%1%'")
% drvExtension);
/* Construct the "masked" store derivation, which is the final one
except that in the list of outputs, the output paths are empty,
and the corresponding environment variables have an empty
value. This ensures that changes in the set of output names do
get reflected in the hash.
if (outputHash != "") {
/* Handle fixed-output derivations. */
if (outputs.size() != 1 || *(outputs.begin()) != "out")
throw Error("multiple outputs are not supported in fixed-output derivations");
However, for fixed-output derivations, we can compute the
output path directly, so we don't need this. */
bool fixedOnly = true;
foreach (StringSet::iterator, i, outputs) {
if (*i != "out" || outputHash == "") {
drv.env[*i] = "";
drv.outputs[*i] = DerivationOutput("", "", "");
fixedOnly = false;
} else {
/* If an output hash was given, check it, and compute the
output path. */
HashType ht = parseHashType(outputHashAlgo);
if (ht == htUnknown)
throw EvalError(format("unknown hash algorithm `%1%'") % outputHashAlgo);
@ -427,20 +415,27 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
string s = outputHash;
outputHash = printHash(h);
if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName);
drv.env[*i] = outPath;
drv.outputs[*i] = DerivationOutput(outPath, outputHashAlgo, outputHash);
drv.env["out"] = outPath;
drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash);
}
else {
/* Construct the "masked" store derivation, which is the final
one except that in the list of outputs, the output paths
are empty, and the corresponding environment variables have
an empty value. This ensures that changes in the set of
output names do get reflected in the hash. */
foreach (StringSet::iterator, i, outputs) {
drv.env[*i] = "";
drv.outputs[*i] = DerivationOutput("", "", "");
}
/* Use the masked derivation expression to compute the output
path. !!! Isn't it a potential security problem that the name
of each output path (including the suffix) isn't taken into
account? For instance, changing the suffix for one path
(i->first == "out" ...) doesn't affect the hash of the
others. Is that exploitable? */
if (!fixedOnly) {
path. */
Hash h = hashDerivationModulo(drv);
foreach (DerivationOutputs::iterator, i, drv.outputs)
if (i->second.path == "") {
Path outPath = makeOutputPath(i->first, h, drvName);