@@ -138,14 +138,16 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
138138
139139 // Clean fingerprints.
140140 for ( _, layout) in & layouts_with_host {
141- rm_rf_glob ( & layout. fingerprint ( ) . join ( & pkg_dir) , config) ?;
141+ let dir = escape_glob_path ( layout. fingerprint ( ) ) ?;
142+ rm_rf_glob ( & Path :: new ( & dir) . join ( & pkg_dir) , config) ?;
142143 }
143144
144145 for target in pkg. targets ( ) {
145146 if target. is_custom_build ( ) {
146147 // Get both the build_script_build and the output directory.
147148 for ( _, layout) in & layouts_with_host {
148- rm_rf_glob ( & layout. build ( ) . join ( & pkg_dir) , config) ?;
149+ let dir = escape_glob_path ( layout. build ( ) ) ?;
150+ rm_rf_glob ( & Path :: new ( & dir) . join ( & pkg_dir) , config) ?;
149151 }
150152 continue ;
151153 }
@@ -173,18 +175,21 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
173175 // Some files include a hash in the filename, some don't.
174176 let hashed_name = file_type. output_filename ( target, Some ( "*" ) ) ;
175177 let unhashed_name = file_type. output_filename ( target, None ) ;
176- rm_rf_glob ( & dir. join ( & hashed_name) , config) ?;
178+ let dir_glob = escape_glob_path ( dir) ?;
179+ let dir_glob = Path :: new ( & dir_glob) ;
180+
181+ rm_rf_glob ( & dir_glob. join ( & hashed_name) , config) ?;
177182 rm_rf ( & dir. join ( & unhashed_name) , config) ?;
178183 // Remove dep-info file generated by rustc. It is not tracked in
179184 // file_types. It does not have a prefix.
180- let hashed_dep_info = dir . join ( format ! ( "{}-*.d" , crate_name) ) ;
185+ let hashed_dep_info = dir_glob . join ( format ! ( "{}-*.d" , crate_name) ) ;
181186 rm_rf_glob ( & hashed_dep_info, config) ?;
182187 let unhashed_dep_info = dir. join ( format ! ( "{}.d" , crate_name) ) ;
183188 rm_rf ( & unhashed_dep_info, config) ?;
184189 // Remove split-debuginfo files generated by rustc.
185- let split_debuginfo_obj = dir . join ( format ! ( "{}.*.o" , crate_name) ) ;
190+ let split_debuginfo_obj = dir_glob . join ( format ! ( "{}.*.o" , crate_name) ) ;
186191 rm_rf_glob ( & split_debuginfo_obj, config) ?;
187- let split_debuginfo_dwo = dir . join ( format ! ( "{}.*.dwo" , crate_name) ) ;
192+ let split_debuginfo_dwo = dir_glob . join ( format ! ( "{}.*.dwo" , crate_name) ) ;
188193 rm_rf_glob ( & split_debuginfo_dwo, config) ?;
189194
190195 // Remove the uplifted copy.
@@ -197,7 +202,8 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
197202 }
198203 }
199204 // TODO: what to do about build_script_build?
200- let incremental = layout. incremental ( ) . join ( format ! ( "{}-*" , crate_name) ) ;
205+ let dir = escape_glob_path ( layout. incremental ( ) ) ?;
206+ let incremental = Path :: new ( & dir) . join ( format ! ( "{}-*" , crate_name) ) ;
201207 rm_rf_glob ( & incremental, config) ?;
202208 }
203209 }
@@ -207,6 +213,13 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
207213 Ok ( ( ) )
208214}
209215
216+ fn escape_glob_path ( pattern : & Path ) -> CargoResult < String > {
217+ let pattern = pattern
218+ . to_str ( )
219+ . ok_or_else ( || anyhow:: anyhow!( "expected utf-8 path" ) ) ?;
220+ Ok ( glob:: Pattern :: escape ( pattern) )
221+ }
222+
210223fn rm_rf_glob ( pattern : & Path , config : & Config ) -> CargoResult < ( ) > {
211224 // TODO: Display utf8 warning to user? Or switch to globset?
212225 let pattern = pattern
0 commit comments