@@ -5,14 +5,15 @@ use std::{
55 path:: PathBuf ,
66} ;
77
8+ use cap_std:: { ambient_authority, fs:: Dir } ;
89use glob:: glob;
910use oci_spec:: image:: {
1011 ANNOTATION_AUTHORS , ANNOTATION_CREATED , ANNOTATION_DOCUMENTATION , ANNOTATION_LICENSES ,
1112 ANNOTATION_REVISION , ANNOTATION_SOURCE , ANNOTATION_VENDOR , ANNOTATION_VERSION ,
1213} ;
1314use semver:: Version ;
1415use serde:: Serialize ;
15- use snafu:: { OptionExt , ResultExt , Snafu } ;
16+ use snafu:: { OptionExt , ResultExt , Snafu , ensure } ;
1617use time:: format_description:: well_known:: Rfc3339 ;
1718
1819use crate :: {
@@ -55,6 +56,9 @@ pub enum Error {
5556
5657 #[ snafu( display( "failed to parse build arguments" ) ) ]
5758 ParseBuildArguments { source : ParseBuildArgumentsError } ,
59+
60+ #[ snafu( display( "failed to locate containerfile relative to the {path:?} directory" ) ) ]
61+ NoSuchContainerfileExists { path : String } ,
5862}
5963
6064#[ derive( Debug , Snafu ) ]
@@ -329,9 +333,28 @@ impl Bakefile {
329333 args. strip_architecture ,
330334 ) ;
331335
332- let dockerfile = PathBuf :: new ( )
333- . join ( & image_name)
334- . join ( & args. target_containerfile ) ;
336+ // By using a cap-std Dir, we can ensure that the paths provided must be relative to
337+ // the appropriate image folder and wont escape it by providing absolute or relative
338+ // paths with traversals (..).
339+ let image_dir = Dir :: open_ambient_dir ( & image_name, ambient_authority ( ) ) . unwrap ( ) ;
340+
341+ let dockerfile_path = if let Some ( custom_path) = & image_options. dockerfile {
342+ ensure ! (
343+ image_dir. exists( custom_path) ,
344+ NoSuchContainerfileExistsSnafu { path: image_name }
345+ ) ;
346+
347+ PathBuf :: new ( ) . join ( & image_name) . join ( custom_path)
348+ } else {
349+ ensure ! (
350+ image_dir. exists( & args. target_containerfile) ,
351+ NoSuchContainerfileExistsSnafu { path: image_name }
352+ ) ;
353+
354+ PathBuf :: new ( )
355+ . join ( & image_name)
356+ . join ( & args. target_containerfile )
357+ } ;
335358
336359 let target_name = if is_entry {
337360 Self :: format_entry_target_name ( & image_name, & image_version)
@@ -359,7 +382,7 @@ impl Bakefile {
359382 platforms : vec ! [ args. target_platform. clone( ) ] ,
360383 // NOTE (@Techassi): Should this instead be scoped to the folder of the image we build
361384 context : Some ( PathBuf :: from ( "." ) ) ,
362- dockerfile : Some ( dockerfile ) ,
385+ dockerfile : Some ( dockerfile_path ) ,
363386 inherits : vec ! [ COMMON_TARGET_NAME . to_owned( ) ] ,
364387 annotations,
365388 contexts,
0 commit comments