File tree Expand file tree Collapse file tree 2 files changed +20
-2
lines changed
Expand file tree Collapse file tree 2 files changed +20
-2
lines changed Original file line number Diff line number Diff line change @@ -37,11 +37,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
3737 let silent = matches. get_flag ( OPT_SILENT ) || matches. get_flag ( OPT_QUIET ) ;
3838 let verbose = matches. get_flag ( OPT_VERBOSE ) ;
3939
40+ // GNU readlink -f/-e/-m follows symlinks first and then applies `..` (physical resolution).
41+ // ResolveMode::Logical collapses `..` before following links, which yields the opposite order,
42+ // so we choose Physical here for GNU compatibility.
4043 let res_mode = if matches. get_flag ( OPT_CANONICALIZE )
4144 || matches. get_flag ( OPT_CANONICALIZE_EXISTING )
4245 || matches. get_flag ( OPT_CANONICALIZE_MISSING )
4346 {
44- ResolveMode :: Logical
47+ ResolveMode :: Physical
4548 } else {
4649 ResolveMode :: None
4750 } ;
Original file line number Diff line number Diff line change 33// For the full copyright and license information, please view the LICENSE
44// file that was distributed with this source code.
55//
6- // spell-checker:ignore regfile
6+ // spell-checker:ignore regfile parentdir
77
88use uutests:: util:: { TestScenario , get_root_path} ;
99use uutests:: { at_and_ucmd, new_ucmd, path_concat, util_name} ;
@@ -68,6 +68,21 @@ fn test_canonicalize_missing() {
6868 assert_eq ! ( actual, expect) ;
6969}
7070
71+ #[ test]
72+ #[ cfg( unix) ]
73+ fn test_canonicalize_symlink_before_parentdir ( ) {
74+ // GNU readlink follows the symlink first and only then evaluates `..`.
75+ // Logical resolution would collapse `link/..` up front and return the current directory instead.
76+ let ( at, mut ucmd) = at_and_ucmd ! ( ) ;
77+ at. mkdir ( "real" ) ;
78+ at. mkdir ( "real/sub" ) ;
79+ at. relative_symlink_dir ( "real/sub" , "link" ) ;
80+
81+ let actual = ucmd. args ( & [ "-f" , "link/.." ] ) . succeeds ( ) . stdout_move_str ( ) ;
82+ let expect = format ! ( "{}/real\n " , at. root_dir_resolved( ) ) ;
83+ assert_eq ! ( actual, expect) ;
84+ }
85+
7186#[ test]
7287fn test_long_redirection_to_current_dir ( ) {
7388 let ( at, mut ucmd) = at_and_ucmd ! ( ) ;
You can’t perform that action at this time.
0 commit comments