tlc: tighten filepos privacy — 0600 permissions + reindent tests
Filepos DB reveals canonical paths of opened files. Use 0600 instead of default umask (0644) so other users cannot read it. Reindent the HomeGuard struct / scoped_home function inside the #[cfg(test)] mod tests block (functionally correct, just hard to read before).
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/// Saved cursor line/column for a file.
|
||||
@@ -75,9 +77,12 @@ pub fn save(path: &Path, pos: CursorPos) -> std::io::Result<()> {
|
||||
out.push_str(&format!("{}\t{}\t{}\n", k, p.line, p.column));
|
||||
}
|
||||
let mut f = fs::File::create(&fp)?;
|
||||
f.write_all(out.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
let mut perms = f.metadata()?.permissions();
|
||||
perms.set_mode(0o600);
|
||||
f.set_permissions(perms)?;
|
||||
f.write_all(out.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn canonical_key(path: &Path) -> String {
|
||||
std::fs::canonicalize(path)
|
||||
@@ -93,41 +98,48 @@ mod tests {
|
||||
|
||||
static HOME_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
struct HomeGuard {
|
||||
#[allow(dead_code)]
|
||||
lock: std::sync::MutexGuard<'static, ()>,
|
||||
prev_home: Option<std::ffi::OsString>,
|
||||
prev_xdg: Option<std::ffi::OsString>,
|
||||
}
|
||||
struct HomeGuard {
|
||||
#[allow(dead_code)]
|
||||
lock: std::sync::MutexGuard<'static, ()>,
|
||||
prev_home: Option<std::ffi::OsString>,
|
||||
prev_xdg: Option<std::ffi::OsString>,
|
||||
}
|
||||
|
||||
impl Drop for HomeGuard {
|
||||
fn drop(&mut self) {
|
||||
match &self.prev_home {
|
||||
Some(v) => std::env::set_var("HOME", v),
|
||||
None => std::env::remove_var("HOME"),
|
||||
}
|
||||
match &self.prev_xdg {
|
||||
Some(v) => std::env::set_var("XDG_CONFIG_HOME", v),
|
||||
None => std::env::remove_var("XDG_CONFIG_HOME"),
|
||||
impl Drop for HomeGuard {
|
||||
fn drop(&mut self) {
|
||||
match &self.prev_home {
|
||||
Some(v) => std::env::set_var("HOME", v),
|
||||
None => std::env::remove_var("HOME"),
|
||||
}
|
||||
match &self.prev_xdg {
|
||||
Some(v) => std::env::set_var("XDG_CONFIG_HOME", v),
|
||||
None => std::env::remove_var("XDG_CONFIG_HOME"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn scoped_home(dir: &std::path::Path) -> HomeGuard {
|
||||
let lock = HOME_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let prev_home = std::env::var_os("HOME");
|
||||
let prev_xdg = std::env::var_os("XDG_CONFIG_HOME");
|
||||
std::env::set_var("HOME", dir);
|
||||
std::env::remove_var("XDG_CONFIG_HOME");
|
||||
HomeGuard { lock, prev_home, prev_xdg }
|
||||
}
|
||||
fn scoped_home(dir: &std::path::Path) -> HomeGuard {
|
||||
let lock = HOME_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let prev_home = std::env::var_os("HOME");
|
||||
let prev_xdg = std::env::var_os("XDG_CONFIG_HOME");
|
||||
std::env::set_var("HOME", dir);
|
||||
std::env::remove_var("XDG_CONFIG_HOME");
|
||||
HomeGuard {
|
||||
lock,
|
||||
prev_home,
|
||||
prev_xdg,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_and_load_round_trip() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let file = dir.path().join("hello.txt");
|
||||
std::fs::write(&file, "hi\n").unwrap();
|
||||
let pos = CursorPos { line: 7, column: 3 };
|
||||
let pos = CursorPos {
|
||||
line: 7,
|
||||
column: 3,
|
||||
};
|
||||
let _g = scoped_home(dir.path());
|
||||
save(&file, pos).unwrap();
|
||||
assert_eq!(load(&file), Some(pos));
|
||||
@@ -139,9 +151,29 @@ fn scoped_home(dir: &std::path::Path) -> HomeGuard {
|
||||
let file = dir.path().join("hello.txt");
|
||||
std::fs::write(&file, "hi\n").unwrap();
|
||||
let _g = scoped_home(dir.path());
|
||||
save(&file, CursorPos { line: 1, column: 0 }).unwrap();
|
||||
save(&file, CursorPos { line: 9, column: 4 }).unwrap();
|
||||
assert_eq!(load(&file), Some(CursorPos { line: 9, column: 4 }));
|
||||
save(
|
||||
&file,
|
||||
CursorPos {
|
||||
line: 1,
|
||||
column: 0,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
save(
|
||||
&file,
|
||||
CursorPos {
|
||||
line: 9,
|
||||
column: 4,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
load(&file),
|
||||
Some(CursorPos {
|
||||
line: 9,
|
||||
column: 4
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user