printAmbiguous (used by nix-instantiate --eval and nix-env) had a depth parameter, but all callers passed INT_MAX, effectively disabling the limit. The function relied on the C++ stack to eventually overflow, which could cause uncontrolled SIGSEGV crashes on deeply nested pre-forced structures. Now printAmbiguous checks depth against max-call-depth (default 10000) and throws StackOverflowError with a proper trace, consistent with other recursive value traversal functions. The function signature is updated to take EvalState& to access the settings and throw proper errors. The depth parameter now counts up from 0 instead of down from INT_MAX.
59 lines
2.4 KiB
Bash
Executable File
59 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
source common.sh
|
|
|
|
drvPath=$(nix-instantiate simple.nix)
|
|
|
|
test "$(nix-store -q --binding system "$drvPath")" = "$system"
|
|
|
|
echo "derivation is $drvPath"
|
|
|
|
outPath=$(nix-store -rvv "$drvPath")
|
|
|
|
echo "output path is $outPath"
|
|
|
|
[[ ! -w $outPath ]]
|
|
|
|
text=$(cat "$outPath/hello")
|
|
[[ "$text" = "Hello World!" ]]
|
|
|
|
TODO_NixOS
|
|
|
|
# Directed delete: $outPath is not reachable from a root, so it should
|
|
# be deleteable.
|
|
nix-store --delete "$outPath"
|
|
[[ ! -e $outPath/hello ]]
|
|
|
|
outPath="$(NIX_REMOTE='local?store=/foo&real='"$TEST_ROOT"'/real-store' nix-instantiate --readonly-mode hash-check.nix)"
|
|
if test "$outPath" != "/foo/lfy1s6ca46rm5r6w4gg9hc0axiakjcnm-dependencies.drv"; then
|
|
echo "hashDerivationModulo appears broken, got $outPath"
|
|
exit 1
|
|
fi
|
|
|
|
outPath="$(NIX_REMOTE='local?store=/foo&real='"$TEST_ROOT"'/real-store' nix-instantiate --readonly-mode big-derivation-attr.nix)"
|
|
if test "$outPath" != "/foo/xxiwa5zlaajv6xdjynf9yym9g319d6mn-big-derivation-attr.drv"; then
|
|
echo "big-derivation-attr.nix hash appears broken, got $outPath. Memory corruption in large drv attr?"
|
|
exit 1
|
|
fi
|
|
|
|
# Test that nix-instantiate on a deeply nested recurseForDerivations structure
|
|
# produces a controlled stack overflow error rather than a segfault.
|
|
expectStderr 1 nix-instantiate --expr 'let x = { recurseForDerivations = true; more = x; }; in x' \
|
|
| grepQuiet "stack overflow; max-call-depth exceeded"
|
|
|
|
# Test that nix-env -qa --meta on deeply nested meta attributes produces a
|
|
# controlled stack overflow error rather than a segfault.
|
|
echo 'let f = n: { type = "derivation"; name = "test"; system = "x86_64-linux"; meta.nested = f (n + 1); }; in { pkg = f 0; }' > "$TEST_ROOT/deep-meta.nix"
|
|
expectStderr 1 nix-env -qa -f "$TEST_ROOT/deep-meta.nix" --json --meta \
|
|
| grepQuiet "stack overflow; max-call-depth exceeded"
|
|
|
|
# Test that nix-instantiate --eval on a pre-forced deep structure (built with
|
|
# foldl' to avoid thunks) produces a controlled stack overflow error rather than
|
|
# a segfault when printAmbiguous traverses the structure.
|
|
# Note: Without the fix, this test may pass if the system stack is large enough.
|
|
# The fix ensures we get a controlled error at max-call-depth (default 10000)
|
|
# rather than relying on the system stack limit.
|
|
# shellcheck disable=SC2016
|
|
expectStderr 1 nix-instantiate --eval --expr 'builtins.foldl'\'' (acc: _: { inner = acc; }) null (builtins.genList (x: x) 20000)' \
|
|
| grepQuiet "stack overflow; max-call-depth exceeded"
|