fix: Add missing context to builtins.{match,split} results

Without this, it is easy to accidentally generate, e.g., a config file
referencing a store path without recording proper dependency
information.
This commit is contained in:
Damien Diederen 2025-02-18 11:56:35 +01:00
parent 9427c028ec
commit b21b3ad851
3 changed files with 27 additions and 6 deletions

View File

@ -40,10 +40,10 @@ namespace nix {
* Miscellaneous
*************************************************************/
static inline Value * mkString(EvalState & state, const std::csub_match & match)
static inline Value * mkString(EvalState & state, const std::csub_match & match, const NixStringContext & context)
{
Value * v = state.allocValue();
v->mkString({match.first, match.second});
v->mkString({match.first, match.second}, context);
return v;
}
@ -4318,7 +4318,7 @@ void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
if (!match[i + 1].matched)
v2 = &state.vNull;
else
v2 = mkString(state, match[i + 1]);
v2 = mkString(state, match[i + 1], context);
v.mkList(list);
} catch (std::regex_error & e) {
@ -4402,7 +4402,7 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
const auto & match = *i;
// Add a string for non-matched characters.
list[idx++] = mkString(state, match.prefix());
list[idx++] = mkString(state, match.prefix(), context);
// Add a list for matched substrings.
const size_t slen = match.size() - 1;
@ -4413,14 +4413,14 @@ void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
if (!match[si + 1].matched)
v2 = &state.vNull;
else
v2 = mkString(state, match[si + 1]);
v2 = mkString(state, match[si + 1], context);
}
(list[idx++] = state.allocValue())->mkList(list2);
// Add a string for non-matched suffix characters.
if (idx == 2 * len)
list[idx++] = mkString(state, match.suffix());
list[idx++] = mkString(state, match.suffix(), context);
}
assert(idx == 2 * len + 1);

View File

@ -0,0 +1 @@
[ true true true ]

View File

@ -0,0 +1,20 @@
let
s = "${builtins.derivation {
name = "test";
builder = "/bin/sh";
system = "x86_64-linux";
}}";
c = builtins.getContext s;
matchRes = builtins.match ".*(-).*" s;
splitRes = builtins.split "(-)" s;
in
[
(c == builtins.getContext (builtins.head matchRes))
(c == builtins.getContext (builtins.head splitRes))
(c == builtins.getContext (builtins.head (builtins.elemAt splitRes 1)))
]