fix: address audit findings — polling, symlinks, validation, wallpaper removal (v0.7.0)
Three parallel audits (quality, performance, security) identified issues across the codebase. This commit addresses all remaining findings: - Replace busy-loop polling in run_command with child.wait() + timeout thread - Canonicalize ~/.face and AccountsService avatar paths to prevent symlink abuse - Add detect_locale_with() DI function for testable locale detection - Move config I/O from activate() to main() to avoid blocking GTK main loop - Validate background_blur range (0–200), reject invalid values with warning - Remove embedded wallpaper from GResource — moonarch provides it via filesystem (binary size ~3.2MB → ~1.3MB)
This commit is contained in:
+19
-9
@@ -52,20 +52,27 @@ pub fn get_avatar_path_with(
|
||||
username: Option<&str>,
|
||||
accountsservice_dir: &Path,
|
||||
) -> Option<PathBuf> {
|
||||
// ~/.face takes priority
|
||||
// ~/.face takes priority — canonicalize to resolve symlinks
|
||||
let face = home.join(".face");
|
||||
if face.exists() {
|
||||
log::debug!("Avatar: using ~/.face");
|
||||
return Some(face);
|
||||
if let Ok(canonical) = std::fs::canonicalize(&face) {
|
||||
log::debug!("Avatar: using ~/.face ({})", canonical.display());
|
||||
return Some(canonical);
|
||||
}
|
||||
// canonicalize failed (e.g. permissions) — skip rather than return unresolved symlink
|
||||
log::warn!("Avatar: ~/.face exists but canonicalize failed, skipping");
|
||||
}
|
||||
|
||||
// AccountsService icon
|
||||
// AccountsService icon — also canonicalize for consistency
|
||||
if let Some(name) = username {
|
||||
if accountsservice_dir.exists() {
|
||||
let icon = accountsservice_dir.join(name);
|
||||
if icon.exists() {
|
||||
log::debug!("Avatar: using AccountsService icon");
|
||||
return Some(icon);
|
||||
if let Ok(canonical) = std::fs::canonicalize(&icon) {
|
||||
log::debug!("Avatar: using AccountsService icon ({})", canonical.display());
|
||||
return Some(canonical);
|
||||
}
|
||||
log::warn!("Avatar: AccountsService icon exists but canonicalize failed, skipping");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +107,8 @@ mod tests {
|
||||
let face = dir.path().join(".face");
|
||||
fs::write(&face, "fake image").unwrap();
|
||||
let path = get_avatar_path_with(dir.path(), None, Path::new("/nonexistent"));
|
||||
assert_eq!(path, Some(face));
|
||||
let expected = fs::canonicalize(&face).unwrap();
|
||||
assert_eq!(path, Some(expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -111,7 +119,8 @@ mod tests {
|
||||
let icon = icons_dir.join("testuser");
|
||||
fs::write(&icon, "fake image").unwrap();
|
||||
let path = get_avatar_path_with(dir.path(), Some("testuser"), &icons_dir);
|
||||
assert_eq!(path, Some(icon));
|
||||
let expected = fs::canonicalize(&icon).unwrap();
|
||||
assert_eq!(path, Some(expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -124,7 +133,8 @@ mod tests {
|
||||
let icon = icons_dir.join("testuser");
|
||||
fs::write(&icon, "fake image").unwrap();
|
||||
let path = get_avatar_path_with(dir.path(), Some("testuser"), &icons_dir);
|
||||
assert_eq!(path, Some(face));
|
||||
let expected = fs::canonicalize(&face).unwrap();
|
||||
assert_eq!(path, Some(expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user