-
Notifications
You must be signed in to change notification settings - Fork 60
Description
Description:
When running MathCAT in restrictive environments (e.g., container), the calls to std::fs::canonicalize() fail with ACCESS_DENIED errors, preventing MathCAT from initializing.
Problem:
canonicalize() requires the OS to resolve symlinks and validate every component of the path, which involves filesystem-level permission checks. In environments with restricted filesystem access, this fails even when the target files are readable.
The affected locations are:
prefs.rs — PreferenceManager::initialize() (line ~263)
shim_filesystem.rs — canonicalize_shim() and read_to_string_shim()
Expected behavior
MathCAT should gracefully handle canonicalize failures by either
- falling back to constructing an absolute path manually (e.g., joining relative paths with the current working directory) or
- by providing new api like set_rules_dir_with_absolute_path(). I guess, the core logic only needs consistent absolute paths — full symlink resolution is not required.
For the internal testing, I have tried the first approach, it is working in restrictive environments.
prefs.rs:
pub fn initialize(&mut self, rules_dir: PathBuf) -> Result<()> {
#[cfg(not(feature = "include-zip"))]
let rules_dir = match rules_dir.canonicalize() {
Err(_e) => {
// fallback code to absolute path - Start
if rules_dir.is_absolute() {
rules_dir
} else {
std::env::current_dir()
.unwrap_or_default()
.join(&rules_dir)
}
// fallback code to absolute path - end
},
Ok(rules_dir) => rules_dir,
};
shim_filesystem.rs
pub fn canonicalize_shim(path: &Path) -> std::io::Result<PathBuf> {
match path.canonicalize() {
Ok(p) => Ok(p),
Err(_) => {
// Fallback: if canonicalize fails (e.g., ACCESS_DENIED),
// construct an absolute path manually
if path.is_absolute() {
Ok(path.to_path_buf())
} else {
Ok(std::env::current_dir().unwrap_or_default().join(path))
}
}
}
}
pub fn read_to_string_shim(path: &Path) -> Result<String> {
let path = match path.canonicalize() {
Ok(path) => path,
Err(_) => path.to_path_buf(), // fallback option
};
info!("Reading file '{}'", &path.display());
match std::fs::read_to_string(&path) {
Ok(str) => return Ok(str),
Err(e) => bail!("Read error while trying to read {}: {}", &path.display(), e),
}
}
If anyone has any other better solutions to this problem, please share your suggestions.