修复 Windows verbatim AppData 路径权限识别
Project CI / AI game creator shell Rust shard 1/4 (push) Failing after 2m2s
Project CI / AI game creator shell Rust shard 2/4 (push) Failing after 2m15s
Project CI / AI game creator shell Rust shard 3/4 (push) Failing after 2m13s
Project CI / AI game creator shell Rust shard 4/4 (push) Failing after 2m13s
Project CI / AI game creator shell Rust smoke (push) Failing after 1m44s
Project CI / AI game creator shell Rust crates (push) Successful in 2m58s
Project CI / Native shell tests (push) Failing after 4m10s
Project CI / Frontend tests (push) Successful in 4m10s
Project CI / Repository checks (push) Successful in 3m4s
Project CI / AI game creator shell web tests (push) Successful in 2m32s
Project CI / Backend tests (push) Successful in 6m55s
Project CI / AI game creator shell Rust shard 1/4 (push) Failing after 2m2s
Project CI / AI game creator shell Rust shard 2/4 (push) Failing after 2m15s
Project CI / AI game creator shell Rust shard 3/4 (push) Failing after 2m13s
Project CI / AI game creator shell Rust shard 4/4 (push) Failing after 2m13s
Project CI / AI game creator shell Rust smoke (push) Failing after 1m44s
Project CI / AI game creator shell Rust crates (push) Successful in 2m58s
Project CI / Native shell tests (push) Failing after 4m10s
Project CI / Frontend tests (push) Successful in 4m10s
Project CI / Repository checks (push) Successful in 3m4s
Project CI / AI game creator shell web tests (push) Successful in 2m32s
Project CI / Backend tests (push) Successful in 6m55s
归一化 \\?\ 与 \\?\UNC\ 路径后再判断受管 ACL scope 补充 verbatim AppData 回归测试
This commit is contained in:
@@ -27,6 +27,7 @@ fn user_selected_path_grants() -> &'static Mutex<HashMap<String, UserSelectedPat
|
||||
|
||||
#[cfg(windows)]
|
||||
fn normalize_user_selected_path_key(path: &Path) -> Option<String> {
|
||||
let path = normalize_windows_policy_path(path);
|
||||
if !path.is_absolute()
|
||||
|| path
|
||||
.components()
|
||||
@@ -42,6 +43,15 @@ fn normalize_user_selected_path_key(path: &Path) -> Option<String> {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn normalize_windows_policy_path(path: &Path) -> PathBuf {
|
||||
let value = path.to_string_lossy();
|
||||
if let Some(rest) = value.strip_prefix(r"\\?\UNC\") {
|
||||
return PathBuf::from(format!(r"\\{rest}"));
|
||||
}
|
||||
PathBuf::from(value.strip_prefix(r"\\?\").unwrap_or(&value))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn register_game_creator_user_selected_path(path: &Path, is_directory: bool) {
|
||||
let Some(key) = normalize_user_selected_path_key(path) else {
|
||||
@@ -838,6 +848,7 @@ pub(crate) fn validate_game_creator_private_path_ancestors(
|
||||
/// separate, explicit user-selected scope below covers native picker/project
|
||||
/// root results, including projects stored outside the current profile.
|
||||
fn game_creator_private_path_allows_auto_elevation(path: &Path) -> bool {
|
||||
let path = normalize_windows_policy_path(path);
|
||||
if !path.is_absolute()
|
||||
|| path
|
||||
.components()
|
||||
@@ -846,7 +857,10 @@ fn game_creator_private_path_allows_auto_elevation(path: &Path) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
let starts_with_path = |root: &Path| path == root || path.starts_with(root);
|
||||
let starts_with_path = |root: &Path| {
|
||||
let root = normalize_windows_policy_path(root);
|
||||
path == root || path.starts_with(root)
|
||||
};
|
||||
if game_creator_runtime_config_dir()
|
||||
.as_deref()
|
||||
.is_some_and(starts_with_path)
|
||||
@@ -1056,6 +1070,7 @@ pub(crate) fn parse_windows_acl_repair_scope(value: &str) -> Result<WindowsAclRe
|
||||
|
||||
#[cfg(windows)]
|
||||
fn game_creator_runtime_config_repair_scope(path: &Path) -> WindowsAclRepairScope {
|
||||
let path = normalize_windows_policy_path(path);
|
||||
let is_builtin_root = |root: PathBuf| path == root || path.starts_with(root);
|
||||
if let Some(home) = std::env::var_os("USERPROFILE")
|
||||
.or_else(|| std::env::var_os("HOME"))
|
||||
@@ -4506,6 +4521,23 @@ mod private_path_elevation_policy_tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[test]
|
||||
fn verbatim_packaged_appdata_path_keeps_managed_repair_scope() {
|
||||
let root = std::env::var_os("LOCALAPPDATA")
|
||||
.or_else(|| std::env::var_os("APPDATA"))
|
||||
.map(PathBuf::from)
|
||||
.expect("local appdata");
|
||||
let packaged = root.join("world.genarrative.ai-game-creator");
|
||||
let verbatim = PathBuf::from(format!(r"\\?\{}", packaged.display()));
|
||||
|
||||
assert!(game_creator_private_path_allows_auto_elevation(&verbatim));
|
||||
assert_eq!(
|
||||
game_creator_runtime_config_repair_scope(&verbatim),
|
||||
WindowsAclRepairScope::Managed
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[test]
|
||||
fn picker_grant_is_required_and_directory_grant_covers_descendants() {
|
||||
|
||||
Reference in New Issue
Block a user