@@ -75,22 +75,15 @@ impl SaveContext for DiskSaveContext {
7575 type Output = ( ) ;
7676
7777 fn write ( & self , key : Option < & str > ) -> save:: Result < Writer < ' _ > > {
78- // When a human-readable hint is supplied it must be a simple relative file name:
79- // reject absolute paths, parent traversal, and multi-component paths so the prefix
80- // below produces a single, well-formed file name in the manifest directory.
81- if let Some ( key) = key {
78+ // When a human-readable hint is supplied it must be a simple relative file name.
79+ // NOTE:: Absolute paths, parent traversal, and multi-component paths cannot produce a
80+ // single, well-formed file name in the manifest directory, so they are ignored and
81+ // treated as if no hint had been supplied.
82+ let key = key. filter ( |key| {
8283 let mut components = std:: path:: Path :: new ( key) . components ( ) ;
83- match components. next ( ) {
84- Some ( std:: path:: Component :: Normal ( _) ) if components. next ( ) . is_none ( ) => { }
85- _ => {
86- return Err ( save:: Error :: message ( format ! (
87- "artifact file name hint {:?} must be a relative file name with no path \
88- separators",
89- key,
90- ) ) ) ;
91- }
92- }
93- }
84+ matches ! ( components. next( ) , Some ( std:: path:: Component :: Normal ( _) ) )
85+ && components. next ( ) . is_none ( )
86+ } ) ;
9487
9588 let mut files = self
9689 . files
@@ -266,12 +259,21 @@ mod tests {
266259 }
267260
268261 #[ test]
269- fn write_rejects_path_separators_and_traversal ( ) {
262+ fn write_ignores_path_separators_and_traversal ( ) {
270263 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
271264 let ctx = DiskSaveContext :: new ( dir. path ( ) . into ( ) , dir. path ( ) . join ( "meta.json" ) ) . unwrap ( ) ;
272265 for bad in [ "sub/dir.bin" , "../escape.bin" , "/abs.bin" ] {
273- SaveContext :: write ( & ctx, Some ( bad) )
274- . expect_err ( "keys with path separators must be rejected" ) ;
266+ let handle = SaveContext :: write ( & ctx, Some ( bad) )
267+ . expect ( "keys with path separators are treated as anonymous" )
268+ . finish ( )
269+ . unwrap ( ) ;
270+ let mut components = std:: path:: Path :: new ( handle. as_str ( ) ) . components ( ) ;
271+ assert ! (
272+ matches!( components. next( ) , Some ( std:: path:: Component :: Normal ( _) ) )
273+ && components. next( ) . is_none( ) ,
274+ "generated name {:?} must be a single relative file name" ,
275+ handle. as_str( ) ,
276+ ) ;
275277 }
276278 }
277279
0 commit comments