patch-shebangs: fix binary data corrupt after patching
This removes the recently introduced shell based implementation of `sponge` which wasn't capable of managing binary input. Now, a tmpFile under $TMPDIR is created manually and later deleted see: https://github.com/NixOS/nixpkgs/pull/414448#issuecomment-3041238623
This commit is contained in:
parent
1cf013f7d7
commit
a1154d6348
@ -68,31 +68,6 @@ patchShebangs() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# like sponge from moreutils but in pure bash
|
||||
_sponge() {
|
||||
local content
|
||||
local target
|
||||
local restoreReadOnly
|
||||
content=""
|
||||
target="$1"
|
||||
|
||||
# Make file writable if it is read-only
|
||||
if [[ ! -w "$target" ]]; then
|
||||
chmod +w "$target"
|
||||
restoreReadOnly=true
|
||||
fi
|
||||
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
content+="$line"$'\n'
|
||||
done
|
||||
printf '%s' "$content" > "$target"
|
||||
|
||||
# Restore read-only if it was read-only before
|
||||
if [[ -n "${restoreReadOnly:-}" ]]; then
|
||||
chmod -w "$target"
|
||||
fi
|
||||
}
|
||||
|
||||
local f
|
||||
while IFS= read -r -d $'\0' f; do
|
||||
isScript "$f" || continue
|
||||
@ -151,14 +126,31 @@ patchShebangs() {
|
||||
|
||||
# Preserve times, see: https://github.com/NixOS/nixpkgs/pull/33281
|
||||
timestamp=$(stat --printf "%y" "$f")
|
||||
sed -e "1 s|.*|#\!$escapedInterpreterLine|" "$f" | _sponge "$f"
|
||||
|
||||
# Manually create temporary file instead of using sed -i
|
||||
# (sed -i on $out/x creates tmpfile /nix/store/x which fails on macos + sandbox)
|
||||
tmpFile=$(mktemp -t patchShebangs.XXXXXXXXXX)
|
||||
sed -e "1 s|.*|#\!$escapedInterpreterLine|" "$f" > "$tmpFile"
|
||||
|
||||
# Make original file writable if it is read-only
|
||||
local restoreReadOnly
|
||||
if [[ ! -w "$f" ]]; then
|
||||
chmod +w "$f"
|
||||
restoreReadOnly=true
|
||||
fi
|
||||
|
||||
# Replace the original file's content with the patched content
|
||||
# (preserving permissions)
|
||||
cat "$tmpFile" > "$f"
|
||||
rm "$tmpFile"
|
||||
if [[ -n "${restoreReadOnly:-}" ]]; then
|
||||
chmod -w "$f"
|
||||
fi
|
||||
|
||||
touch --date "$timestamp" "$f"
|
||||
fi
|
||||
fi
|
||||
done < <(find "$@" -type f -perm -0100 -print0)
|
||||
|
||||
unset -f _sponge
|
||||
}
|
||||
|
||||
patchShebangsAuto () {
|
||||
|
||||
@ -204,6 +204,44 @@ let
|
||||
// {
|
||||
meta = { };
|
||||
};
|
||||
|
||||
preserves-binary-data =
|
||||
(derivation {
|
||||
name = "preserves-binary-data";
|
||||
system = stdenv.buildPlatform.system;
|
||||
builder = "${stdenv.__bootPackages.stdenv.__bootPackages.bashNonInteractive}/bin/bash";
|
||||
initialPath = [
|
||||
stdenv.__bootPackages.stdenv.__bootPackages.coreutils
|
||||
];
|
||||
strictDeps = false;
|
||||
args = [
|
||||
"-c"
|
||||
''
|
||||
set -euo pipefail
|
||||
. ${../../stdenv/generic/setup.sh}
|
||||
. ${../../build-support/setup-hooks/patch-shebangs.sh}
|
||||
mkdir -p $out/bin
|
||||
# Create a script with binary data after the shebang
|
||||
echo "#!/bin/bash" > $out/bin/test
|
||||
echo "echo 'script start'" >> $out/bin/test
|
||||
# Add some binary data (null bytes and other non-printable chars)
|
||||
printf '\x00\x01\x02\xff\xfe' >> $out/bin/test
|
||||
echo >> $out/bin/test
|
||||
echo "echo 'script end'" >> $out/bin/test
|
||||
chmod +x $out/bin/test
|
||||
patchShebangs $out/bin/test
|
||||
# Verify binary data is still present by checking file size and content
|
||||
if ! printf '\x00\x01\x02\xff\xfe' | cmp -s - <(sed -n '3p' $out/bin/test | tr -d '\n'); then
|
||||
echo "Binary data corrupted during patching"
|
||||
exit 1
|
||||
fi
|
||||
''
|
||||
];
|
||||
assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null";
|
||||
})
|
||||
// {
|
||||
meta = { };
|
||||
};
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
@ -219,6 +257,7 @@ stdenv.mkDerivation {
|
||||
read-only-script
|
||||
preserves-read-only
|
||||
preserves-timestamp
|
||||
preserves-binary-data
|
||||
;
|
||||
};
|
||||
buildCommand = ''
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user