@@ -896,20 +896,31 @@ fn verify_cwd() -> Result<()> {
896896 Ok ( ( ) )
897897}
898898
899- // Set the HOME environment variable if it is not already set or is empty.
899+ /// Set the HOME environment variable if it is not already set or is empty.
900900fn set_home_env_if_not_exists ( envs : & mut HashMap < String , String > , uid : Uid ) {
901901 if envs. get ( "HOME" ) . is_none_or ( |v| v. is_empty ( ) ) {
902902 if let Some ( dir_home) = utils:: get_user_home ( uid. into ( ) ) {
903- envs . insert ( "HOME" . to_owned ( ) , dir_home. to_string_lossy ( ) . to_string ( ) ) ;
903+ set_home_from_path ( envs , & dir_home) ;
904904 }
905905 }
906906}
907907
908+ /// Set the HOME environment variable if dir_home string is valid UTF-8
909+ fn set_home_from_path ( envs : & mut HashMap < String , String > , dir_home : & Path ) {
910+ if let Some ( home_str) = dir_home. to_str ( ) {
911+ envs. insert ( "HOME" . to_owned ( ) , home_str. to_owned ( ) ) ;
912+ }
913+ }
914+
908915#[ cfg( test) ]
909916mod tests {
910917 use std:: fs;
918+ use std:: ffi:: OsStr ;
919+ use std:: os:: unix:: ffi:: OsStrExt ;
920+ use std:: path:: PathBuf ;
911921
912922 use anyhow:: Result ;
923+ use nix:: unistd:: { Uid , User as NixUser } ;
913924 #[ cfg( feature = "libseccomp" ) ]
914925 use nix:: unistd;
915926 use oci_spec:: runtime:: { LinuxNamespaceBuilder , SpecBuilder , UserBuilder } ;
@@ -1206,6 +1217,15 @@ mod tests {
12061217 assert_eq ! ( envs. get( "HOME" ) , Some ( & "/existing/home" . to_string( ) ) ) ;
12071218 }
12081219
1220+ #[ test]
1221+ fn test_set_home_env_if_not_exists_already_exists_non_root ( ) {
1222+ let mut envs = HashMap :: new ( ) ;
1223+ envs. insert ( "HOME" . to_owned ( ) , "/existing/home" . to_owned ( ) ) ;
1224+
1225+ set_home_env_if_not_exists ( & mut envs, Uid :: current ( ) ) ;
1226+ assert_eq ! ( envs. get( "HOME" ) , Some ( & "/existing/home" . to_string( ) ) ) ;
1227+ }
1228+
12091229 #[ test]
12101230 fn test_set_home_env_if_not_exists_already_exists_but_empty_value ( ) {
12111231 let mut envs = HashMap :: new ( ) ;
@@ -1215,11 +1235,63 @@ mod tests {
12151235 assert_eq ! ( envs. get( "HOME" ) , Some ( & "/root" . to_string( ) ) ) ;
12161236 }
12171237
1238+ #[ test]
1239+ fn test_set_home_env_if_not_exists_already_exists_but_empty_value_non_root ( ) {
1240+ let mut envs = HashMap :: new ( ) ;
1241+ envs. insert ( "HOME" . to_owned ( ) , "" . to_owned ( ) ) ;
1242+
1243+ let current_uid = Uid :: current ( ) ;
1244+ let expected = NixUser :: from_uid ( current_uid)
1245+ . ok ( )
1246+ . flatten ( )
1247+ . and_then ( |user| user. dir . to_str ( ) . map ( |s| s. to_owned ( ) ) )
1248+ . unwrap_or_default ( ) ;
1249+
1250+ set_home_env_if_not_exists ( & mut envs, current_uid) ;
1251+ assert_eq ! ( envs. get( "HOME" ) , Some ( & expected) ) ;
1252+ }
1253+
12181254 #[ test]
12191255 fn test_set_home_env_if_not_exists_not_set ( ) {
12201256 let mut envs = HashMap :: new ( ) ;
12211257
12221258 set_home_env_if_not_exists ( & mut envs, Uid :: from_raw ( 0 ) ) ;
12231259 assert_eq ! ( envs. get( "HOME" ) , Some ( & "/root" . to_string( ) ) ) ;
12241260 }
1261+
1262+ #[ test]
1263+ fn test_set_home_env_if_not_exists_not_set_non_root ( ) {
1264+ let mut envs = HashMap :: new ( ) ;
1265+
1266+ let current_uid = Uid :: current ( ) ;
1267+ let expected = NixUser :: from_uid ( current_uid)
1268+ . ok ( )
1269+ . flatten ( )
1270+ . and_then ( |user| user. dir . to_str ( ) . map ( |s| s. to_owned ( ) ) )
1271+ . unwrap_or_default ( ) ;
1272+
1273+ set_home_env_if_not_exists ( & mut envs, current_uid) ;
1274+ assert_eq ! ( envs. get( "HOME" ) , Some ( & expected) ) ;
1275+ }
1276+
1277+ #[ test]
1278+ fn test_set_home_from_path_valid_utf8 ( ) {
1279+ let mut envs = HashMap :: new ( ) ;
1280+ let valid_path = PathBuf :: from ( "/home/user" ) ;
1281+
1282+ set_home_from_path ( & mut envs, & valid_path) ;
1283+ assert_eq ! ( envs. get( "HOME" ) , Some ( & "/home/user" . to_string( ) ) ) ;
1284+ }
1285+
1286+ #[ test]
1287+ fn test_set_home_from_path_invalid_utf8 ( ) {
1288+ let mut envs = HashMap :: new ( ) ;
1289+
1290+ let invalid_bytes = b"/home/user/\xFF \xFE " ;
1291+ let invalid_path = PathBuf :: from ( OsStr :: from_bytes ( invalid_bytes) ) ;
1292+ assert ! ( invalid_path. to_str( ) . is_none( ) ) ;
1293+
1294+ set_home_from_path ( & mut envs, & invalid_path) ;
1295+ assert_eq ! ( envs. get( "HOME" ) , None ) ;
1296+ }
12251297}
0 commit comments