History

remove `pwd` crate dependency in favor of using libc directly

…to obtain the home directory of a user with the given name. `pwd` still uses failure and appears unmaintained as PRs remain open for more than a month now.

Sebastian Thiel committed 4 years ago

Commit 4adfa111 parent a1981d44 files · +24 −107Browse files

Unified · Split

4 files
  1. Cargo.lock +1 −96
  2. git-config/Cargo.toml +3 −1
  3. git-config/src/lib.rs +1 −2
  4. git-config/src/values.rs +19 −8
Cargo.lock+1−96
@@ -2,15 +2,6 @@ · 1 unmodified line
22 # It is not intended for manual editing.
33 version = 3
44
5−[[package]]
6−name = "addr2line"
7−version = "0.17.0"
8−source = "registry+https://github.com/rust-lang/crates.io-index"
9−checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
10−dependencies = [
11− "gimli",
12−]
13−
145 [[package]]
156 name = "adler"
167 version = "1.0.2"
@@ -231,21 +222,6 @@ version = "1.1.0" · 214 unmodified lines
231222 source = "registry+https://github.com/rust-lang/crates.io-index"
232223 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
233224
234−[[package]]
235−name = "backtrace"
236−version = "0.3.65"
237−source = "registry+https://github.com/rust-lang/crates.io-index"
238−checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
239−dependencies = [
240− "addr2line",
241− "cc",
242− "cfg-if",
243− "libc",
244− "miniz_oxide",
245− "object",
246− "rustc-demangle",
247−]
248−
249225 [[package]]
250226 name = "base64"
251227 version = "0.13.0"
@@ -934,28 +910,6 @@ version = "2.5.2" · 682 unmodified lines
934910 source = "registry+https://github.com/rust-lang/crates.io-index"
935911 checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
936912
937−[[package]]
938−name = "failure"
939−version = "0.1.8"
940−source = "registry+https://github.com/rust-lang/crates.io-index"
941−checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
942−dependencies = [
943− "backtrace",
944− "failure_derive",
945−]
946−
947−[[package]]
948−name = "failure_derive"
949−version = "0.1.8"
950−source = "registry+https://github.com/rust-lang/crates.io-index"
951−checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
952−dependencies = [
953− "proc-macro2",
954− "quote",
955− "syn",
956− "synstructure",
957−]
958−
959913 [[package]]
960914 name = "fastrand"
961915 version = "1.7.0"
@@ -1085,12 +1039,6 @@ dependencies = [ · 123 unmodified lines
10851039 "wasi",
10861040 ]
10871041
1088−[[package]]
1089−name = "gimli"
1090−version = "0.26.1"
1091−source = "registry+https://github.com/rust-lang/crates.io-index"
1092−checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
1093−
10941042 [[package]]
10951043 name = "git-actor"
10961044 version = "0.10.0"
@@ -1165,9 +1113,9 @@ dependencies = [ · 68 unmodified lines
11651113 "git-ref",
11661114 "git-sec",
11671115 "git-testtools",
1116+ "libc",
11681117 "memchr",
11691118 "nom",
1170− "pwd",
11711119 "serde",
11721120 "serde_derive",
11731121 "serial_test",
@@ -2187,15 +2135,6 @@ dependencies = [ · 1013 unmodified lines
21872135 "libc",
21882136 ]
21892137
2190−[[package]]
2191−name = "object"
2192−version = "0.28.4"
2193−source = "registry+https://github.com/rust-lang/crates.io-index"
2194−checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
2195−dependencies = [
2196− "memchr",
2197−]
2198−
21992138 [[package]]
22002139 name = "object-access"
22012140 version = "0.1.0"
@@ -2463,16 +2402,6 @@ dependencies = [ · 261 unmodified lines
24632402 "unicase",
24642403 ]
24652404
2466−[[package]]
2467−name = "pwd"
2468−version = "1.3.1"
2469−source = "registry+https://github.com/rust-lang/crates.io-index"
2470−checksum = "f9ca0304857594109dca88140120427c7a65027be6b77d86a5938588e79cb07b"
2471−dependencies = [
2472− "failure",
2473− "libc",
2474−]
2475−
24762405 [[package]]
24772406 name = "quick-error"
24782407 version = "2.0.1"
@@ -2562,12 +2491,6 @@ dependencies = [ · 83 unmodified lines
25622491 "winapi",
25632492 ]
25642493
2565−[[package]]
2566−name = "rustc-demangle"
2567−version = "0.1.21"
2568−source = "registry+https://github.com/rust-lang/crates.io-index"
2569−checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
2570−
25712494 [[package]]
25722495 name = "rustc-hash"
25732496 version = "1.1.0"
@@ -2835,18 +2758,6 @@ dependencies = [ · 261 unmodified lines
28352758 "unicode-ident",
28362759 ]
28372760
2838−[[package]]
2839−name = "synstructure"
2840−version = "0.12.6"
2841−source = "registry+https://github.com/rust-lang/crates.io-index"
2842−checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
2843−dependencies = [
2844− "proc-macro2",
2845− "quote",
2846− "syn",
2847− "unicode-xid",
2848−]
2849−
28502761 [[package]]
28512762 name = "tar"
28522763 version = "0.4.38"
@@ -3080,12 +2991,6 @@ version = "0.1.9" · 227 unmodified lines
30802991 source = "registry+https://github.com/rust-lang/crates.io-index"
30812992 checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
30822993
3083−[[package]]
3084−name = "unicode-xid"
3085−version = "0.2.3"
3086−source = "registry+https://github.com/rust-lang/crates.io-index"
3087−checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
3088−
30892994 [[package]]
30902995 name = "url"
30912996 version = "2.2.2"
git-config/Cargo.toml+3−1
@@ -24,11 +24,13 @@ dirs = "4" · 23 unmodified lines
2424 nom = { version = "7", default_features = false, features = [ "std" ] }
2525 memchr = "2"
2626 serde_crate = { version = "1", package = "serde", optional = true }
27−pwd = "1.3.1"
2827 thiserror = "1.0.26"
2928 unicode-bom = "1.1.4"
3029 bstr = { version = "0.2.13", default-features = false, features = ["std"] }
3130
31+[target.'cfg(not(windows))'.dependencies]
32+libc = "0.2"
33+
3234 [dev-dependencies]
3335 git-testtools = { path = "../tests/tools"}
3436 serial_test = "0.6.0"
git-config/src/lib.rs+1−2
@@ -1,5 +1,4 @@
1−#![forbid(unsafe_code)]
2−#![deny(rust_2018_idioms)]
1+#![deny(unsafe_code, rust_2018_idioms)]
32 // #![warn(missing_docs)]
43 // #![warn(clippy::pedantic, clippy::nursery)]
54
git-config/src/values.rs+19−8
@@ -191,7 +191,23 @@ pub mod path { · 190 unmodified lines
191191 use std::borrow::Cow;
192192
193193 #[cfg(not(any(target_os = "android", target_os = "windows")))]
194− use pwd::Passwd;
194+ fn home_for_user(name: &str) -> Option<std::path::PathBuf> {
195+ let cname = std::ffi::CString::new(name).ok()?;
196+ // SAFETY: calling this in a threaded program that modifies the pw database is not actually safe.
197+ // TODO: use the `*_r` version, but it's much harder to use.
198+ #[allow(unsafe_code)]
199+ let pwd = unsafe { libc::getpwnam(cname.as_ptr()) };
200+ if pwd.is_null() {
201+ None
202+ } else {
203+ use std::os::unix::ffi::OsStrExt;
204+ // SAFETY: pw_dir is a cstr and it lives as long as… well, we hope nobody changes the pw database while we are at it
205+ // from another thread. Otherwise it lives long enough.
206+ #[allow(unsafe_code)]
207+ let cstr = unsafe { std::ffi::CStr::from_ptr((*pwd).pw_dir) };
208+ Some(std::ffi::OsStr::from_bytes(cstr.to_bytes()).into())
209+ }
210+ }
195211
196212 use crate::values::Path;
197213
@@ -210,8 +226,6 @@ pub mod path { · 12 unmodified lines
210226 },
211227 #[error("Ill-formed UTF-8 in username")]
212228 UsernameConversion(#[from] std::str::Utf8Error),
213− #[error("User home info missing")]
214− PwdFileQuery,
215229 #[error("User interpolation is not available on this platform")]
216230 UserInterpolationUnsupported,
217231 }
@@ -281,10 +295,7 @@ pub mod path { · 63 unmodified lines
281295 .ok_or(interpolate::Error::Missing { what: "/" })?;
282296 let (username, path_with_leading_slash) = val.split_at(i);
283297 let username = std::str::from_utf8(username)?;
284− let home = Passwd::from_name(username)
285− .map_err(|_| interpolate::Error::PwdFileQuery)?
286− .ok_or(interpolate::Error::Missing { what: "pwd user info" })?
287− .dir;
298+ let home = home_for_user(username).ok_or(interpolate::Error::Missing { what: "pwd user info" })?;
288299 let path_past_user_prefix =
289300 git_path::try_from_byte_slice(&path_with_leading_slash["/".len()..]).map_err(|err| {
290301 interpolate::Error::Utf8Conversion {
@@ -292,7 +303,7 @@ pub mod path { · 1 unmodified line
292303 err,
293304 }
294305 })?;
295− Ok(std::path::PathBuf::from(home).join(path_past_user_prefix).into())
306+ Ok(home.join(path_past_user_prefix).into())
296307 }
297308 }
298309 }