Skip to content

Commit effe587

Browse files
authored
fix(core): scope checks on Android (#8420)
* fix(core): scope checks on Android On Android, when we call canonicalize() on "/data/user/0/appid" (which is the data dir), the result is a "/data/data/appid" path, so we need to adjust our scope for that. * clarify code * apply the logic to all targets
1 parent b59f2f5 commit effe587

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

.changes/fix-android-scope.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:bug
3+
---
4+
5+
Fixes file scope checks on Android.

core/tauri/src/scope/fs.rs

+45-5
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,54 @@ fn push_pattern<P: AsRef<Path>, F: Fn(&str) -> Result<Pattern, glob::PatternErro
7979
) -> crate::Result<()> {
8080
let path: PathBuf = pattern.as_ref().components().collect();
8181
list.insert(f(&path.to_string_lossy())?);
82-
#[cfg(windows)]
83-
{
84-
if let Ok(p) = std::fs::canonicalize(&path) {
85-
list.insert(f(&p.to_string_lossy())?);
82+
83+
let mut path = path;
84+
let mut checked_path = None;
85+
86+
// attempt to canonicalize parents in case we have a path like `/data/user/0/appid/**`
87+
// where `**` obviously does not exist but we need to canonicalize the parent
88+
//
89+
// example: given the `/data/user/0/appid/assets/*` path,
90+
// it's a glob pattern so it won't exist (canonicalize() fails);
91+
//
92+
// the second iteration needs to check `/data/user/0/appid/assets` and save the `*` component to append later.
93+
//
94+
// if it also does not exist, a third iteration is required to check `/data/user/0/appid`
95+
// with `assets/*` as the cached value (`checked_path` variable)
96+
// on Android that gets canonicalized to `/data/data/appid` so the final value will be `/data/data/appid/assets/*`
97+
// which is the value we want to check when we execute the `is_allowed` function
98+
let canonicalized = loop {
99+
if let Ok(path) = path.canonicalize() {
100+
break Some(if let Some(p) = checked_path {
101+
path.join(p)
102+
} else {
103+
path
104+
});
105+
}
106+
107+
// get the last component of the path as an OsStr
108+
let last = path.iter().next_back().map(PathBuf::from);
109+
if let Some(mut p) = last {
110+
// remove the last component of the path
111+
// so the next iteration checks its parent
112+
path.pop();
113+
// append the already checked path to the last component
114+
if let Some(checked_path) = &checked_path {
115+
p.push(checked_path);
116+
}
117+
// replace the checked path with the current value
118+
checked_path.replace(p);
86119
} else {
87-
list.insert(f(&format!("\\\\?\\{}", path.display()))?);
120+
break None;
88121
}
122+
};
123+
124+
if let Some(p) = canonicalized {
125+
list.insert(f(&p.to_string_lossy())?);
126+
} else if cfg!(windows) {
127+
list.insert(f(&format!("\\\\?\\{}", path.display()))?);
89128
}
129+
90130
Ok(())
91131
}
92132

0 commit comments

Comments
 (0)