use std::path::{Path, PathBuf};
use std::process::Command;
fn onelf() -> &'static str {
env!("CARGO_BIN_EXE_onelf")
}
fn have(cmd: &str) -> bool {
Command::new(cmd)
.arg("--version")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
fn patchelf() -> Option<String> {
if let Ok(p) = std::env::var("ONELF_PATCHELF") {
if Path::new(&p).is_file() {
return Some(p);
}
}
have("patchelf").then(|| "patchelf".to_string())
}
fn workdir(tag: &str) -> PathBuf {
let d = std::env::temp_dir().join(format!(
"onelf-it-{tag}-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
std::fs::create_dir_all(&d).unwrap();
d
}
fn write(path: &Path, content: &str) {
if let Some(p) = path.parent() {
std::fs::create_dir_all(p).unwrap();
}
std::fs::write(path, content).unwrap();
}
fn cc(src: &Path, out: &Path) -> bool {
let compiler = if have("cc") {
"cc"
} else if have("gcc") {
"gcc"
} else {
eprintln!("skip: no C compiler available");
return false;
};
let st = Command::new(compiler)
.args(["-O0", "-o"])
.arg(out)
.arg(src)
.status()
.unwrap();
assert!(st.success(), "compiling {} failed", src.display());
true
}
fn run_onelf(args: &[&str], cwd: Option<&Path>) -> std::process::Output {
let mut c = Command::new(onelf());
c.args(args);
if let Some(d) = cwd {
c.current_dir(d);
}
c.output().expect("spawn onelf")
}
#[test]
fn store_mode_roundtrips_byte_exact() {
let td = workdir("store");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
let data: Vec<u8> = (0..200_000u32)
.map(|i| (i.wrapping_mul(2654435761) >> 13) as u8)
.collect();
std::fs::create_dir_all(app.join("bin")).unwrap();
std::fs::write(app.join("bin/data.bin"), &data).unwrap();
let pkg = td.join("s.onelf");
let o = run_onelf(
&[
"pack",
"--no-compress",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let outdir = td.join("out");
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
outdir.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"extract: {}",
String::from_utf8_lossy(&o.stderr)
);
let got = std::fs::read(outdir.join("bin/data.bin")).unwrap();
assert_eq!(got, data, "stored payload did not round-trip");
let o = run_onelf(&["info", pkg.to_str().unwrap()], None);
let info = String::from_utf8_lossy(&o.stdout);
assert!(
info.contains("100.0%") || info.contains("ratio: 100"),
"expected 100% ratio in `info`, got:\n{info}"
);
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn preload_list_is_emitted() {
let td = workdir("preload");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
let pkg = td.join("p.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--preload",
"${ONELF_DIR}/lib/libfoo.so",
"--preload",
"libbar.so",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
"-",
"--file",
".onelf/preload",
],
None,
);
assert!(o.status.success());
let body = String::from_utf8_lossy(&o.stdout);
assert!(body.contains("${ONELF_DIR}/lib/libfoo.so"), "got: {body:?}");
assert!(body.contains("libbar.so"), "got: {body:?}");
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn extract_masks_mode_bits_by_default() {
use std::os::unix::fs::PermissionsExt;
let td = workdir("mode");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
std::fs::create_dir_all(app.join("bin")).unwrap();
let suid = app.join("bin/suid");
std::fs::write(&suid, b"x").unwrap();
std::fs::set_permissions(&suid, std::fs::Permissions::from_mode(0o4755)).unwrap();
let pkg = td.join("m.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let out = td.join("out");
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
out.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"extract: {}",
String::from_utf8_lossy(&o.stderr)
);
let mode = std::fs::metadata(out.join("bin/suid"))
.unwrap()
.permissions()
.mode();
assert_eq!(
mode & 0o7777,
0o755,
"setuid bit must be stripped by default"
);
let out2 = td.join("out2");
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
out2.to_str().unwrap(),
"--preserve-mode",
],
None,
);
assert!(
o.status.success(),
"extract --preserve-mode: {}",
String::from_utf8_lossy(&o.stderr)
);
let mode = std::fs::metadata(out2.join("bin/suid"))
.unwrap()
.permissions()
.mode();
assert_eq!(mode & 0o7777, 0o4755, "--preserve-mode must keep setuid");
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn extract_refuses_escaping_symlink() {
let td = workdir("evil-link");
let app = td.join("app");
std::fs::create_dir_all(app.join("bin")).unwrap();
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
std::os::unix::fs::symlink("../../../../etc/passwd", app.join("bin/evil")).unwrap();
let pkg = td.join("e.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let out = td.join("out");
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
out.to_str().unwrap(),
],
None,
);
assert!(
!o.status.success(),
"extraction of an escaping symlink must fail; stderr: {}",
String::from_utf8_lossy(&o.stderr)
);
assert!(
out.join("bin/evil").symlink_metadata().is_err(),
"escaping symlink was materialized"
);
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn malformed_manifest_errors_cleanly() {
let td = workdir("malformed");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
let pkg = td.join("bad.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let mut bytes = std::fs::read(&pkg).unwrap();
let flen = bytes.len();
let mut footer_buf = [0u8; onelf_format::FOOTER_SIZE];
footer_buf.copy_from_slice(&bytes[flen - onelf_format::FOOTER_SIZE..]);
let footer = onelf_format::Footer::from_bytes(&footer_buf).expect("valid footer");
let start = footer.manifest_offset as usize;
let end = (start + footer.manifest_compressed as usize).min(flen);
assert!(start < end, "manifest region should be non-empty");
for b in &mut bytes[start..end] {
*b ^= 0xff;
}
std::fs::write(&pkg, &bytes).unwrap();
let o = run_onelf(&["info", pkg.to_str().unwrap()], None);
let stderr = String::from_utf8_lossy(&o.stderr);
assert!(
!stderr.contains("panicked"),
"info panicked on a corrupt package: {stderr}"
);
assert!(
!o.status.success(),
"info must fail on a corrupt manifest; stderr: {stderr}"
);
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn build_is_byte_deterministic() {
{
let probe = workdir("det-probe");
let ok = cc_libm(&probe.join("p.c"), &probe.join("p"));
let _ = std::fs::remove_dir_all(&probe);
if !ok {
return; }
}
let build = |tag: &str| -> Vec<u8> {
let td = workdir(tag);
let app = td.join("app");
std::fs::create_dir_all(app.join("bin")).unwrap();
assert!(
cc_libm(&td.join("prog.c"), &app.join("bin/prog")),
"compiler vanished mid-test"
);
write(
&app.join("onelf.toml"),
"[package]\nname=\"det\"\ncommand=\"bin/prog\"\n\n\
[env]\nZULU=\"1\"\nALPHA=\"2\"\nMIKE=\"3\"\n",
);
let mut c = Command::new(onelf());
c.arg("build")
.current_dir(&app)
.env("SOURCE_DATE_EPOCH", "1700000000");
if let Some(pe) = patchelf() {
c.env("ONELF_PATCHELF", pe);
}
let o = c.output().expect("spawn onelf build");
assert!(
o.status.success(),
"build: {}",
String::from_utf8_lossy(&o.stderr)
);
let bytes = std::fs::read(app.join("det.onelf")).expect("output package");
let _ = std::fs::remove_dir_all(&td);
bytes
};
let a = build("det-a");
let b = build("det-b");
assert_eq!(
a,
b,
"two builds of the same tree must be byte-identical (len {} vs {})",
a.len(),
b.len()
);
}
#[test]
fn corrupt_manifest_checksum_fails_to_run() {
use std::os::unix::fs::PermissionsExt;
let td = workdir("checksum");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
let pkg = td.join("c.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let mut bytes = std::fs::read(&pkg).unwrap();
let n = bytes.len();
for b in &mut bytes[n - 12..n - 8] {
*b ^= 0xff;
}
std::fs::write(&pkg, &bytes).unwrap();
std::fs::set_permissions(&pkg, std::fs::Permissions::from_mode(0o755)).unwrap();
let out = Command::new(&pkg)
.env("HOME", td.to_str().unwrap())
.output()
.expect("run corrupt package");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
!out.status.success(),
"a corrupt-checksum package must not run; stderr: {stderr}"
);
assert!(
stderr.contains("manifest checksum mismatch"),
"failure must come from the checksum gate, not an unrelated error; stderr: {stderr}"
);
let _ = std::fs::remove_dir_all(&td);
}
fn cc_libm(src: &Path, out: &Path) -> bool {
let compiler = if have("cc") {
"cc"
} else if have("gcc") {
"gcc"
} else {
return false;
};
write(
src,
"#include <math.h>\n#include <stdio.h>\n\
int main(){printf(\"%f\\n\", sqrt(2.0));return 0;}\n",
);
Command::new(compiler)
.args(["-O0", "-o"])
.arg(out)
.arg(src)
.arg("-lm")
.status()
.map(|s| s.success())
.unwrap_or(false)
}
#[test]
fn env_survives_sandboxed_reexec() {
let td = workdir("reexec");
let app = td.join("app");
std::fs::create_dir_all(app.join("bin")).unwrap();
let result = td.join("result");
let src = td.join("harness.c");
write(
&src,
&format!(
r#"#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv) {{
const char *v = getenv("ONELF_IT_VAR");
const char *d = getenv("ONELF_IT_DIR");
if (getenv("ONELF_IT_RX")) {{
FILE *f = fopen("{res}", "w");
int ok = v && !strcmp(v, "survived") && d && strstr(d, "/data");
fprintf(f, "%s v=[%s] d=[%s]\n", ok ? "PASS" : "FAIL",
v ? v : "(null)", d ? d : "(null)");
fclose(f);
return ok ? 0 : 1;
}}
/* first launch -> wipe env, mark, re-exec self (sandbox sim) */
clearenv();
setenv("ONELF_IT_RX", "1", 1);
execv("/proc/self/exe", argv);
return 3;
}}
"#,
res = result.display()
),
);
if !cc(&src, &app.join("bin/harness")) {
return; }
write(
&app.join("onelf.toml"),
"[package]\nname=\"itest\"\ncommand=\"bin/harness\"\n\n\
[env]\nONELF_IT_VAR=\"survived\"\nONELF_IT_DIR=\"${ONELF_DIR}/data\"\n",
);
let mut c = Command::new(onelf());
c.arg("build").current_dir(&app);
if let Some(pe) = patchelf() {
c.env("ONELF_PATCHELF", pe);
}
let o = c.output().expect("spawn onelf build");
let log = String::from_utf8_lossy(&o.stderr).into_owned();
assert!(o.status.success(), "build failed:\n{log}");
let pkg = app.join("itest.onelf");
assert!(pkg.is_file(), "no package produced\n{log}");
let st = Command::new(&pkg)
.env_clear()
.env("PATH", "/usr/bin:/bin")
.env("HOME", td.to_str().unwrap())
.status()
.expect("run package");
if patchelf().is_some() {
assert!(
log.contains("Injected onelf-env"),
"expected onelf-env DT_NEEDED injection:\n{log}"
);
let r = std::fs::read_to_string(&result)
.expect("post-re-exec process must have written the result file");
assert!(r.starts_with("PASS"), "re-exec env not restored: {r}");
assert!(st.success());
} else {
assert!(
log.contains("patchelf unavailable")
|| log.contains("not sandbox-re-exec-safe")
|| log.contains("re-exec-safe env"),
"expected a fail-loud patchelf warning:\n{log}"
);
}
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn bin_on_path_by_default_and_runtime_env_expansion() {
let td = workdir("defpath");
let app = td.join("app");
std::fs::create_dir_all(app.join("bin")).unwrap();
let result = td.join("result");
let hsrc = td.join("probe.c");
write(&hsrc, "int main(void){return 77;}\n");
if !cc(&hsrc, &app.join("bin/onelf_helper")) {
return; }
let asrc = td.join("app.c");
write(
&asrc,
&format!(
r#"#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void) {{
FILE *f = fopen("{res}", "w");
fprintf(f, "PATH=%s\n", getenv("PATH") ? getenv("PATH") : "(null)");
fprintf(f, "FOO=%s\n", getenv("ONELF_IT_FOO") ? getenv("ONELF_IT_FOO") : "(null)");
int rc = 127;
if (fork() == 0) {{
execvp("onelf_helper", (char *[]){{ "onelf_helper", NULL }});
_exit(127);
}}
int st; wait(&st); rc = WEXITSTATUS(st);
fprintf(f, "HELPER=%d\n", rc);
fclose(f);
return 0;
}}"#,
res = result.display()
),
);
if !cc(&asrc, &app.join("bin/app")) {
return;
}
write(
&app.join("onelf.toml"),
"[package]\nname=\"defpath\"\ncommand=\"bin/app\"\n\n\
[env]\nONELF_IT_FOO=\"pre-${ONELF_DIR}-$${HOME}-post\"\n",
);
let mut cmd = Command::new(onelf());
cmd.arg("build").current_dir(&app);
if let Some(pe) = patchelf() {
cmd.env("ONELF_PATCHELF", pe);
}
let o = cmd.output().expect("spawn onelf build");
assert!(
o.status.success(),
"build failed:\n{}",
String::from_utf8_lossy(&o.stderr)
);
let pkg = app.join("defpath.onelf");
let st = Command::new(&pkg)
.env_clear()
.env("HOME", "/xyzhome")
.env("PATH", "/sentinel/dir")
.status()
.expect("run package");
assert!(st.success());
let r = std::fs::read_to_string(&result).expect("result file");
let path_line = r.lines().find(|l| l.starts_with("PATH=")).unwrap_or("");
assert!(
path_line.contains("/bin:/sentinel/dir"),
"expected bin/ prepended to inherited PATH, got: {path_line}"
);
let foo = r.lines().find(|l| l.starts_with("FOO=")).unwrap_or("");
assert!(
foo.starts_with("FOO=pre-/") && foo.ends_with("-/xyzhome-post"),
"runtime env expansion wrong: {foo}"
);
assert!(
r.contains("HELPER=77"),
"bundled helper not found via default PATH:\n{r}"
);
let st = Command::new(&pkg)
.env_clear()
.env("HOME", td.to_str().unwrap())
.status()
.expect("run package (empty PATH)");
assert!(st.success());
let r = std::fs::read_to_string(&result).expect("result file");
let path_line = r.lines().find(|l| l.starts_with("PATH=")).unwrap_or("");
assert!(
path_line.ends_with("/bin:/usr/bin:/bin"),
"empty PATH should fall back to /usr/bin:/bin (no dangling ':'), got: {path_line}"
);
assert!(
!path_line.ends_with(':'),
"PATH must not end in an empty element: {path_line}"
);
assert!(
r.contains("HELPER=77"),
"bundled helper not found with fallback PATH:\n{r}"
);
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn readonly_directory_children_still_extract() {
use std::os::unix::fs::PermissionsExt;
let td = workdir("ro-dir");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
write(&app.join("ro/data.txt"), "payload\n");
std::fs::set_permissions(app.join("ro"), std::fs::Permissions::from_mode(0o555)).unwrap();
let pkg = td.join("ro.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"pack: {}",
String::from_utf8_lossy(&o.stderr)
);
let out = td.join("out");
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
out.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"extract: {}",
String::from_utf8_lossy(&o.stderr)
);
let got = std::fs::read_to_string(out.join("ro/data.txt")).expect("child under 0555 dir");
assert_eq!(got, "payload\n");
let mode = std::fs::metadata(out.join("ro"))
.unwrap()
.permissions()
.mode()
& 0o777;
assert_eq!(
mode, 0o555,
"directory mode must be applied after extraction"
);
let o = run_onelf(
&[
"extract",
pkg.to_str().unwrap(),
"--output",
out.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"re-extract into a pre-existing read-only dir: {}",
String::from_utf8_lossy(&o.stderr)
);
let got = std::fs::read_to_string(out.join("ro/data.txt")).expect("child re-extracted");
assert_eq!(got, "payload\n");
for ro in [app.join("ro"), out.join("ro")] {
let _ = std::fs::set_permissions(&ro, std::fs::Permissions::from_mode(0o755));
}
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn source_onelf_path_is_rejected() {
let td = workdir("reserved");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
write(&app.join(".onelf/env"), "FOO=bar\n");
let pkg = td.join("r.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
!o.status.success(),
"packing a reserved .onelf/ path must fail"
);
let stderr = String::from_utf8_lossy(&o.stderr);
assert!(
stderr.contains(".onelf"),
"error should name the reserved path; got: {stderr}"
);
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn recipe_expansion_cannot_inject_keys() {
let td = workdir("recipe-inj");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
write(
&app.join("onelf.toml"),
"[package]\ncommand = \"bin/run.sh\"\ndescription = \"${ONELF_INJ}\"\n\n[bundle]\nskip = true\n",
);
let pkg = td.join("i.onelf");
let payload = "evil\"\nname = \"HACKED";
let o = Command::new(onelf())
.args([
"build",
app.to_str().unwrap(),
"--output",
pkg.to_str().unwrap(),
])
.env("ONELF_INJ", payload)
.output()
.expect("spawn onelf build");
assert!(
o.status.success(),
"build: {}",
String::from_utf8_lossy(&o.stderr)
);
let o = run_onelf(&["info", pkg.to_str().unwrap()], None);
let info = String::from_utf8_lossy(&o.stdout);
assert!(
info.contains("HACKED"),
"injected marker must survive as a literal description value:\n{info}"
);
let _ = std::fs::remove_dir_all(&td);
}
#[test]
fn source_onelf_assets_are_accepted() {
let td = workdir("assets");
let app = td.join("app");
write(&app.join("bin/run.sh"), "#!/bin/sh\necho hi\n");
write(&app.join(".onelf/icons/default.png"), "PNGDATA");
write(
&app.join(".onelf/desktop/default.desktop"),
"[Desktop Entry]\nName=App\nExec=run.sh\n",
);
let pkg = td.join("a.onelf");
let o = run_onelf(
&[
"pack",
"--command",
"bin/run.sh",
"--output",
pkg.to_str().unwrap(),
app.to_str().unwrap(),
],
None,
);
assert!(
o.status.success(),
"packing .onelf/icons and .onelf/desktop must succeed; got: {}",
String::from_utf8_lossy(&o.stderr)
);
let icon_out = td.join("out.png");
let i = run_onelf(
&[
"icon",
pkg.to_str().unwrap(),
"-o",
icon_out.to_str().unwrap(),
],
None,
);
assert!(i.status.success(), "icon extract failed");
assert_eq!(std::fs::read(&icon_out).unwrap(), b"PNGDATA");
let desk_out = td.join("out.desktop");
let d = run_onelf(
&[
"desktop",
pkg.to_str().unwrap(),
"-o",
desk_out.to_str().unwrap(),
],
None,
);
assert!(d.status.success(), "desktop extract failed");
assert!(
String::from_utf8_lossy(&std::fs::read(&desk_out).unwrap()).contains("Name=App"),
"extracted desktop file should carry the source content"
);
let _ = std::fs::remove_dir_all(&td);
}