File: 0003-Extract-and-test-x-mode-setting-logic.patch

package info (click to toggle)
rust-gix-worktree-state 0.16.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 216 kB
  • sloc: makefile: 4
file content (111 lines) | stat: -rw-r--r-- 3,828 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
From bf33d2b49212f71a7af1aef34e0ffac41140815b Mon Sep 17 00:00:00 2001
From: Eliah Kagan <degeneracypressure@gmail.com>
Date: Fri, 10 Jan 2025 17:41:52 -0500
Subject: [PATCH 3/4] Extract and test +x mode setting logic

---
 src/checkout/entry.rs | 81 ++++++++++++++++++++++--
 1 file changed, 75 insertions(+), 6 deletions(-)

Index: gix-worktree-state/src/checkout/entry.rs
===================================================================
--- gix-worktree-state.orig/src/checkout/entry.rs
+++ gix-worktree-state/src/checkout/entry.rs
@@ -1,5 +1,5 @@
-use std::borrow::Cow;
 use std::{
+    borrow::Cow,
     fs::OpenOptions,
     io::Write,
     path::{Path, PathBuf},
@@ -285,12 +285,8 @@ pub(crate) fn finalize_entry(
     // For possibly existing, overwritten files, we must change the file mode explicitly.
     #[cfg(unix)]
     if let Some(path) = set_executable_after_creation {
-        use std::os::unix::fs::PermissionsExt;
         let mut perm = std::fs::symlink_metadata(path)?.permissions();
-        let mut mode = perm.mode();
-        mode &= 0o777; // Clear non-rwx bits (setuid, setgid, sticky).
-        mode |= (mode & 0o444) >> 2; // Let readers also execute.
-        perm.set_mode(mode);
+        set_mode_executable(&mut perm);
         std::fs::set_permissions(path, perm)?;
     }
     // NOTE: we don't call `file.sync_all()` here knowing that some filesystems don't handle this well.
@@ -299,3 +295,76 @@ pub(crate) fn finalize_entry(
     file.close()?;
     Ok(())
 }
+
+#[cfg(unix)]
+fn set_mode_executable(perm: &mut std::fs::Permissions) {
+    use std::os::unix::fs::PermissionsExt;
+    let mut mode = perm.mode();
+    mode &= 0o777; // Clear non-rwx bits (setuid, setgid, sticky).
+    mode |= (mode & 0o444) >> 2; // Let readers also execute.
+    perm.set_mode(mode);
+}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    #[cfg(unix)]
+    fn set_mode_executable() {
+        let cases = [
+            // Common cases.
+            (0o100755, 0o755),
+            (0o100644, 0o755),
+            (0o100750, 0o750),
+            (0o100640, 0o750),
+            (0o100700, 0o700),
+            (0o100600, 0o700),
+            (0o100775, 0o775),
+            (0o100664, 0o775),
+            (0o100770, 0o770),
+            (0o100660, 0o770),
+            (0o100764, 0o775),
+            (0o100760, 0o770),
+            // Some less common cases.
+            (0o100674, 0o775),
+            (0o100670, 0o770),
+            (0o100000, 0o000),
+            (0o100400, 0o500),
+            (0o100440, 0o550),
+            (0o100444, 0o555),
+            (0o100462, 0o572),
+            (0o100242, 0o252),
+            (0o100167, 0o177),
+            // Some cases with set-user-ID, set-group-ID, and sticky bits.
+            (0o104755, 0o755),
+            (0o104644, 0o755),
+            (0o102755, 0o755),
+            (0o102644, 0o755),
+            (0o101755, 0o755),
+            (0o101644, 0o755),
+            (0o106755, 0o755),
+            (0o106644, 0o755),
+            (0o104750, 0o750),
+            (0o104640, 0o750),
+            (0o102750, 0o750),
+            (0o102640, 0o750),
+            (0o101750, 0o750),
+            (0o101640, 0o750),
+            (0o106750, 0o750),
+            (0o106640, 0o750),
+            (0o107644, 0o755),
+            (0o107000, 0o000),
+            (0o106400, 0o500),
+            (0o102462, 0o572),
+        ];
+        for (old, expected) in cases {
+            use std::os::unix::fs::PermissionsExt;
+            let mut perm = std::fs::Permissions::from_mode(old);
+            super::set_mode_executable(&mut perm);
+            let actual = perm.mode();
+            assert_eq!(
+                actual, expected,
+                "{old:06o} should become {expected:04o} but became {actual:04o}"
+            );
+        }
+    }
+}