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 }
|
clap = { workspace = true }
|
||||||
pkgar = "0.2.2"
|
pkgar = "0.2.2"
|
||||||
pkgar-core = "0.2.2"
|
pkgar-core = "0.2.2"
|
||||||
|
tempfile = "3"
|
||||||
termion = "4.0.6"
|
termion = "4.0.6"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ impl AppContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_library(&self) -> Result<Library, pkg::backend::Error> {
|
fn open_library(&self) -> Result<Library, pkg::backend::Error> {
|
||||||
|
self.ensure_install_layout()?;
|
||||||
let callback = new_pkg_callback();
|
let callback = new_pkg_callback();
|
||||||
Library::new(&self.install_path, &self.target, callback)
|
Library::new(&self.install_path, &self.target, callback)
|
||||||
}
|
}
|
||||||
@@ -154,6 +155,7 @@ impl AppContext {
|
|||||||
source_dir: &Path,
|
source_dir: &Path,
|
||||||
pubkey_dir: &Path,
|
pubkey_dir: &Path,
|
||||||
) -> Result<Library, pkg::backend::Error> {
|
) -> Result<Library, pkg::backend::Error> {
|
||||||
|
self.ensure_install_layout()?;
|
||||||
let callback = new_pkg_callback();
|
let callback = new_pkg_callback();
|
||||||
Library::new_local(
|
Library::new_local(
|
||||||
source_dir,
|
source_dir,
|
||||||
@@ -163,6 +165,11 @@ impl AppContext {
|
|||||||
callback,
|
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>> {
|
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>> {
|
fn get_aur_recipe(package: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
validate_git_target(package)?;
|
||||||
let repo_url = aur_repo_url(package);
|
let repo_url = aur_repo_url(package);
|
||||||
let clone_dir = create_temp_dir("cub-aur-get")?;
|
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("clone")
|
||||||
.arg("--depth")
|
.arg("--depth")
|
||||||
.arg("1")
|
.arg("1")
|
||||||
|
.arg("--")
|
||||||
.arg(&repo_url)
|
.arg(&repo_url)
|
||||||
.arg(&clone_dir)
|
.arg(&clone_dir)
|
||||||
.status()?;
|
.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>> {
|
fn import_aur_target(target: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
validate_git_target(target)?;
|
||||||
let repo_url = aur_repo_url(target);
|
let repo_url = aur_repo_url(target);
|
||||||
let clone_dir = create_temp_dir("cub-aur")?;
|
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("clone")
|
||||||
.arg("--depth")
|
.arg("--depth")
|
||||||
.arg("1")
|
.arg("1")
|
||||||
|
.arg("--")
|
||||||
.arg(&repo_url)
|
.arg(&repo_url)
|
||||||
.arg(&clone_dir)
|
.arg(&clone_dir)
|
||||||
.status()?;
|
.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>> {
|
fn create_temp_dir(prefix: &str) -> Result<PathBuf, Box<dyn std::error::Error>> {
|
||||||
let base = env::temp_dir();
|
let path = tempfile::Builder::new().prefix(prefix).tempdir()?.keep();
|
||||||
let nanos = SystemTime::now()
|
Ok(path)
|
||||||
.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())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_dir_recursive(src: &Path, dst: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
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"
|
"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 }
|
pkgar-keys = { version = "0.2.2", optional = true }
|
||||||
|
|
||||||
# HTTP for source fetching
|
# 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]
|
[features]
|
||||||
default = ["full"]
|
default = ["full"]
|
||||||
|
|||||||
Reference in New Issue
Block a user