<!-- agent --> Windows canonicalization can produce verbatim paths with a `\\?\` prefix while included configuration metadata uses an ordinary drive path. Comparing those representations directly prevents an explicitly safe config file from being promoted to full trust, including after repository reloads. Canonicalize both the path under test and configured safe-directory paths through the filesystem before exact or wildcard comparison. Retain the existing lexical realpath fallback for missing paths.
Unified · Split
| @@ -609,10 +609,12 @@ fn check_safe_directories( · 608 unmodified lines | |||
| 609 | safe_dirs: &[BString], | 609 | safe_dirs: &[BString], |
| 610 | ) -> Result<(), Error> { | 610 | ) -> Result<(), Error> { |
| 611 | let mut is_safe = false; | 611 | let mut is_safe = false; |
| 612 | let path_to_test = match gix_path::realpath_opts(path_to_test, current_dir, gix_path::realpath::MAX_SYMLINKS) { | 612 | let realpath_or_original = |path: &std::path::Path| { |
| 613 | Ok(p) => p, | 613 | std::fs::canonicalize(path) |
| 614 | Err(_) => path_to_test.to_owned(), | 614 | .or_else(|_| gix_path::realpath_opts(path, current_dir, gix_path::realpath::MAX_SYMLINKS)) |
| 615 | .unwrap_or_else(|_| path.to_owned()) | ||
| 615 | }; | 616 | }; |
| 617 | let path_to_test = realpath_or_original(path_to_test); | ||
| 616 | for safe_dir in safe_dirs { | 618 | for safe_dir in safe_dirs { |
| 617 | let safe_dir = safe_dir.as_bstr(); | 619 | let safe_dir = safe_dir.as_bstr(); |
| 618 | if safe_dir == "*" { | 620 | if safe_dir == "*" { |
| @@ -638,10 +640,10 @@ fn check_safe_directories( · 19 unmodified lines | |||
| 638 | } | 640 | } |
| 639 | if safe_dir.ends_with("*") { | 641 | if safe_dir.ends_with("*") { |
| 640 | let safe_dir = safe_dir.parent().expect("* is last component"); | 642 | let safe_dir = safe_dir.parent().expect("* is last component"); |
| 641 | if path_to_test.strip_prefix(safe_dir).is_ok() { | 643 | if path_to_test.strip_prefix(realpath_or_original(safe_dir)).is_ok() { |
| 642 | is_safe = true; | 644 | is_safe = true; |
| 643 | } | 645 | } |
| 644 | } else if safe_dir == path_to_test { | 646 | } else if realpath_or_original(&safe_dir) == path_to_test { |
| 645 | is_safe = true; | 647 | is_safe = true; |
| 646 | } | 648 | } |
| 647 | } | 649 | } |