File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -281,6 +281,16 @@ impl Params {
281281 let prefix_str = prefix_path. to_string_lossy ( ) ;
282282 if prefix_str. ends_with ( MAIN_SEPARATOR ) {
283283 ( prefix_path, String :: new ( ) )
284+ } else if prefix_from_template. ends_with ( "/." ) || prefix_from_template == "." {
285+ // Path normalizes trailing '.' away, making both parent() and file_name()
286+ // return wrong results for hidden files like /tmp/.XXXXXXXX.
287+ // Use prefix_from_template directly instead.
288+ let directory = Path :: new ( & prefix_from_option)
289+ . join ( & prefix_from_template[ ..prefix_from_template. len ( ) - 1 ] ) ; // strip trailing '.'
290+
291+ let prefix = "." . to_string ( ) ;
292+
293+ ( directory, prefix)
284294 } else {
285295 let directory = match prefix_path. parent ( ) {
286296 None => PathBuf :: new ( ) ,
Original file line number Diff line number Diff line change @@ -1172,3 +1172,24 @@ fn test_non_utf8_tmpdir_directory_creation() {
11721172 // but we can verify the command succeeds
11731173 ucmd. arg ( "-d" ) . arg ( "-p" ) . arg ( at. plus ( dir_name) ) . succeeds ( ) ;
11741174}
1175+
1176+ #[ test]
1177+ #[ cfg( unix) ]
1178+ fn test_mktemp_hidden_file_single_dot ( ) {
1179+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
1180+ let dir = tempdir ( ) . unwrap ( ) ;
1181+ let template = dir. path ( ) . join ( ".XXXXXX" ) ;
1182+
1183+ let result = scene. ucmd ( ) . arg ( template. to_str ( ) . unwrap ( ) ) . succeeds ( ) ;
1184+
1185+ let path = result. stdout_str ( ) . trim ( ) ;
1186+ assert ! (
1187+ std:: path:: Path :: new( path)
1188+ . file_name( )
1189+ . unwrap( )
1190+ . to_str( )
1191+ . unwrap( )
1192+ . starts_with( '.' ) ,
1193+ "expected hidden file, got {path}"
1194+ ) ;
1195+ }
You can’t perform that action at this time.
0 commit comments