@@ -9,8 +9,8 @@ use std::io::Write;
99/// uid/gid/name), plus an entry with no ownership metadata at all.
1010/// Action: `pna experimental chown` changing only the user.
1111/// Expectation: The un-overridden group side stays absent (no gid facet, never
12- /// a synthesized 0); the overridden user side is set; mode is preserved; the
13- /// no-ownership entry is left untouched .
12+ /// a synthesized 0); the overridden user side is set even for a metadata-empty
13+ /// entry; existing mode is preserved; absent mode stays absent .
1414#[ test]
1515fn chown_user_only_preserves_missing_gid ( ) {
1616 setup ( ) ;
@@ -44,6 +44,7 @@ fn chown_user_only_preserves_missing_gid() {
4444 path,
4545 "new_user" ,
4646 "mode_only.txt" ,
47+ "bare.txt" ,
4748 "--no-owner-lookup" ,
4849 ] )
4950 . unwrap ( )
@@ -69,9 +70,9 @@ fn chown_user_only_preserves_missing_gid() {
6970 assert_eq ! ( m. permission_mode( ) . unwrap( ) . get( ) , 0o644 ) ;
7071 }
7172 "bare.txt" => {
72- assert ! ( m. owner_uid( ) . is_none( ) ) ;
73+ assert_eq ! ( m. owner_user_name( ) . unwrap( ) . as_str( ) , "new_user" ) ;
74+ assert_eq ! ( m. owner_uid( ) . unwrap( ) . get( ) , u64 :: MAX ) ;
7375 assert ! ( m. owner_gid( ) . is_none( ) ) ;
74- assert ! ( m. owner_user_name( ) . is_none( ) ) ;
7576 assert ! ( m. owner_group_name( ) . is_none( ) ) ;
7677 assert ! ( m. permission_mode( ) . is_none( ) ) ;
7778 }
@@ -82,7 +83,8 @@ fn chown_user_only_preserves_missing_gid() {
8283 assert_eq ! ( count, 2 , "archive should contain exactly 2 entries" ) ;
8384}
8485
85- /// Precondition: An archive entry carries only a permission mode (no owner uid/gid).
86+ /// Precondition: Archive entries carry either only a permission mode or no
87+ /// ownership metadata at all.
8688/// Action: `pna experimental chown` changing only the group (`:new_grp`).
8789/// Expectation: The un-overridden user side stays absent (no uid facet, never a synthesized 0).
8890#[ test]
@@ -99,6 +101,13 @@ fn chown_group_only_preserves_missing_uid() {
99101 mo. permission_mode ( pna:: PermissionMode :: from ( 0o600 ) ) ;
100102 mo. write_all ( b"m" ) . unwrap ( ) ;
101103 a. add_entry ( mo. build ( ) . unwrap ( ) ) . unwrap ( ) ;
104+ let mut bare = EntryBuilder :: new_file (
105+ EntryName :: from_utf8_preserve_root ( "bare.txt" ) ,
106+ WriteOptions :: store ( ) ,
107+ )
108+ . unwrap ( ) ;
109+ bare. write_all ( b"x" ) . unwrap ( ) ;
110+ a. add_entry ( bare. build ( ) . unwrap ( ) ) . unwrap ( ) ;
102111 a. finalize ( ) . unwrap ( ) ;
103112 }
104113
@@ -111,6 +120,7 @@ fn chown_group_only_preserves_missing_uid() {
111120 path,
112121 ":new_grp" ,
113122 "mode_only.txt" ,
123+ "bare.txt" ,
114124 "--no-owner-lookup" ,
115125 ] )
116126 . unwrap ( )
@@ -119,14 +129,26 @@ fn chown_group_only_preserves_missing_uid() {
119129
120130 archive:: for_each_entry ( path, |entry| {
121131 let m = entry. metadata ( ) ;
122- assert_eq ! ( m. owner_group_name( ) . unwrap( ) . as_str( ) , "new_grp" ) ;
123- assert_eq ! ( m. owner_gid( ) . unwrap( ) . get( ) , u64 :: MAX ) ;
124- assert ! (
125- m. owner_uid( ) . is_none( ) ,
126- "un-overridden uid must stay absent, not synthesized to 0"
127- ) ;
128- assert ! ( m. owner_user_name( ) . is_none( ) ) ;
129- assert_eq ! ( m. permission_mode( ) . unwrap( ) . get( ) , 0o600 ) ;
132+ match entry. header ( ) . path ( ) . as_str ( ) {
133+ "mode_only.txt" => {
134+ assert_eq ! ( m. owner_group_name( ) . unwrap( ) . as_str( ) , "new_grp" ) ;
135+ assert_eq ! ( m. owner_gid( ) . unwrap( ) . get( ) , u64 :: MAX ) ;
136+ assert ! (
137+ m. owner_uid( ) . is_none( ) ,
138+ "un-overridden uid must stay absent, not synthesized to 0"
139+ ) ;
140+ assert ! ( m. owner_user_name( ) . is_none( ) ) ;
141+ assert_eq ! ( m. permission_mode( ) . unwrap( ) . get( ) , 0o600 ) ;
142+ }
143+ "bare.txt" => {
144+ assert_eq ! ( m. owner_group_name( ) . unwrap( ) . as_str( ) , "new_grp" ) ;
145+ assert_eq ! ( m. owner_gid( ) . unwrap( ) . get( ) , u64 :: MAX ) ;
146+ assert ! ( m. owner_uid( ) . is_none( ) ) ;
147+ assert ! ( m. owner_user_name( ) . is_none( ) ) ;
148+ assert ! ( m. permission_mode( ) . is_none( ) ) ;
149+ }
150+ other => panic ! ( "unexpected entry: {other}" ) ,
151+ }
130152 } )
131153 . unwrap ( ) ;
132154}
0 commit comments