use super::project::render_install_sh;
use std::path::Path;
const PIE_EXECUTED_MARKER: &str = "FAKE_PIE_WAS_EXECUTED";
const REMOVED_VERSION_SNIFFING_GATE: &str = r#"
need_pie_install=true
if command -v pie >/dev/null 2>&1; then
current="$(pie --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo '0.0.0')"
if printf '%s\n%s\n' "1.3.7" "$current" | sort -V -C; then
need_pie_install=false
fi
fi
if [[ "$need_pie_install" == "false" ]]; then
PIE="pie"
"$PIE" install "pkg:1.0.0"
exit 0
fi
"#;
fn write_executable(path: &Path, body: &str) {
use std::os::unix::fs::PermissionsExt as _;
std::fs::write(path, body).expect("write script");
let mut permissions = std::fs::metadata(path).expect("metadata").permissions();
permissions.set_mode(0o755);
std::fs::set_permissions(path, permissions).expect("chmod");
}
fn poisoned_path(root: &Path) -> String {
let bin = root.join("bin");
std::fs::create_dir_all(&bin).expect("create sandbox bin dir");
write_executable(
&bin.join("pie"),
&format!(
"#!/bin/sh\ntouch '{}'\necho 'PIE 9.9.9'\nexit 0\n",
root.join(PIE_EXECUTED_MARKER).display()
),
);
write_executable(
&bin.join("curl"),
concat!(
"#!/bin/sh\n",
"out=''\n",
"while [ $# -gt 0 ]; do\n",
" case \"$1\" in --output) out=\"$2\"; shift 2;; *) shift;; esac\n",
"done\n",
"printf 'not-the-real-phar' > \"$out\"\n"
),
);
format!("{}:/usr/bin:/bin", bin.display())
}
fn run_bootstrap(root: &Path, script: &str) -> std::process::Output {
let path = poisoned_path(root);
let script_path = root.join("bootstrap.sh");
std::fs::write(&script_path, script).expect("write bootstrap script");
std::process::Command::new("/bin/bash")
.arg(&script_path)
.current_dir(root)
.env_clear()
.env("PATH", path)
.env("HOME", root)
.output()
.expect("/bin/bash should start")
}
fn bootstrap_section(content: &str) -> String {
let start = content.find("PIE_VERSION=").expect("PIE_VERSION pin present");
let end = content
.find("# Install the extension binary into the running PHP's extension dir.")
.expect("bootstrap section ends before the extension install");
format!(
"set -euo pipefail\n{}\n\"$PIE\" install \"pkg:1.0.0\"\n",
&content[start..end]
)
}
#[test]
fn preinstalled_pie_on_path_is_never_executed() {
let root = tempfile::tempdir().expect("tempdir");
let content = render_install_sh("test/pkg", "ext", "1.0.0");
let output = run_bootstrap(root.path(), &bootstrap_section(&content));
assert!(
!root.path().join(PIE_EXECUTED_MARKER).exists(),
"the preinstalled `pie` on PATH was executed; stderr:\n{}",
String::from_utf8_lossy(&output.stderr)
);
assert!(
!output.status.success(),
"a stub download must not pass the digest check; stdout:\n{}",
String::from_utf8_lossy(&output.stdout)
);
assert!(
String::from_utf8_lossy(&output.stderr).contains("checksum mismatch"),
"the script must reach the digest comparison rather than short-circuiting to the \
preinstalled binary; stderr:\n{}",
String::from_utf8_lossy(&output.stderr)
);
}
#[test]
fn the_removed_version_sniffing_gate_would_have_executed_the_fake_pie() {
let root = tempfile::tempdir().expect("tempdir");
let script = format!("set -euo pipefail\n{REMOVED_VERSION_SNIFFING_GATE}");
let output = run_bootstrap(root.path(), &script);
assert!(
root.path().join(PIE_EXECUTED_MARKER).exists(),
"the pre-fix gate must execute the fake `pie`, otherwise the control test proves \
nothing; stderr:\n{}",
String::from_utf8_lossy(&output.stderr)
);
}
#[test]
fn the_generated_script_has_no_path_based_interpreter_fallback() {
let content = render_install_sh("test/pkg", "ext", "1.0.0");
for forbidden in [
"command -v pie",
"need_pie_install",
"PIE=\"pie\"",
"sort -V -C",
"1.3.7",
] {
assert!(
!content.contains(forbidden),
"install.sh must not reintroduce a PATH-based PIE fallback ({forbidden:?}), got:\n{content}"
);
}
assert!(
content.contains("PIE=\"$pie_dir/pie\""),
"the interpreter must always be the verified PHAR, got:\n{content}"
);
let verify = content.find("checksum mismatch").expect("digest gate present");
let assign = content.find("PIE=\"$pie_dir/pie\"").expect("interpreter assigned");
assert!(verify < assign, "the digest must be checked before `$PIE` is chosen");
}