fix: harden Cub git and tempdir handling
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -18,6 +18,7 @@ redox-pkg = { git = "https://gitlab.redox-os.org/redox-os/pkgutils.git", default
|
||||
clap = { workspace = true }
|
||||
pkgar = "0.2.2"
|
||||
pkgar-core = "0.2.2"
|
||||
tempfile = "3"
|
||||
termion = "4.0.6"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -145,6 +145,7 @@ impl AppContext {
|
||||
}
|
||||
|
||||
fn open_library(&self) -> Result<Library, pkg::backend::Error> {
|
||||
self.ensure_install_layout()?;
|
||||
let callback = new_pkg_callback();
|
||||
Library::new(&self.install_path, &self.target, callback)
|
||||
}
|
||||
@@ -154,6 +155,7 @@ impl AppContext {
|
||||
source_dir: &Path,
|
||||
pubkey_dir: &Path,
|
||||
) -> Result<Library, pkg::backend::Error> {
|
||||
self.ensure_install_layout()?;
|
||||
let callback = new_pkg_callback();
|
||||
Library::new_local(
|
||||
source_dir,
|
||||
@@ -163,6 +165,11 @@ impl AppContext {
|
||||
callback,
|
||||
)
|
||||
}
|
||||
|
||||
fn ensure_install_layout(&self) -> Result<(), pkg::backend::Error> {
|
||||
fs::create_dir_all(self.install_path.join("etc/pkg.d"))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
@@ -542,6 +549,7 @@ fn fetch_bur_recipe(package: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
|
||||
fn get_aur_recipe(package: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
validate_git_target(package)?;
|
||||
let repo_url = aur_repo_url(package);
|
||||
let clone_dir = create_temp_dir("cub-aur-get")?;
|
||||
|
||||
@@ -549,6 +557,7 @@ fn get_aur_recipe(package: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
.arg("clone")
|
||||
.arg("--depth")
|
||||
.arg("1")
|
||||
.arg("--")
|
||||
.arg(&repo_url)
|
||||
.arg(&clone_dir)
|
||||
.status()?;
|
||||
@@ -609,6 +618,7 @@ fn inspect_target(context: &AppContext, target: &str) -> Result<(), Box<dyn std:
|
||||
}
|
||||
|
||||
fn import_aur_target(target: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
validate_git_target(target)?;
|
||||
let repo_url = aur_repo_url(target);
|
||||
let clone_dir = create_temp_dir("cub-aur")?;
|
||||
|
||||
@@ -616,6 +626,7 @@ fn import_aur_target(target: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
.arg("clone")
|
||||
.arg("--depth")
|
||||
.arg("1")
|
||||
.arg("--")
|
||||
.arg(&repo_url)
|
||||
.arg(&clone_dir)
|
||||
.status()?;
|
||||
@@ -1151,25 +1162,8 @@ fn render_conversion_report(report: &ConversionReport) -> String {
|
||||
}
|
||||
|
||||
fn create_temp_dir(prefix: &str) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||
let base = env::temp_dir();
|
||||
let nanos = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.map(|duration| duration.as_nanos())
|
||||
.unwrap_or(0);
|
||||
|
||||
for attempt in 0..128 {
|
||||
let candidate = base.join(format!("{prefix}-{}-{nanos}-{attempt}", std::process::id()));
|
||||
if !candidate.exists() {
|
||||
fs::create_dir_all(&candidate)?;
|
||||
return Ok(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::AlreadyExists,
|
||||
format!("failed to allocate temporary directory for {prefix}"),
|
||||
)
|
||||
.into())
|
||||
let path = tempfile::Builder::new().prefix(prefix).tempdir()?.keep();
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
fn copy_dir_recursive(src: &Path, dst: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
||||
@@ -1236,3 +1230,15 @@ fn yes_no(value: bool) -> &'static str {
|
||||
"no"
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_git_target(target: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if target.trim_start().starts_with('-') {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
format!("invalid git target: {target}"),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ pkgar-core = { version = "0.2.2", optional = true }
|
||||
pkgar-keys = { version = "0.2.2", optional = true }
|
||||
|
||||
# HTTP for source fetching
|
||||
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"], optional = true }
|
||||
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls", "json"], optional = true }
|
||||
serde_json = "1"
|
||||
|
||||
[features]
|
||||
default = ["full"]
|
||||
|
||||
Reference in New Issue
Block a user