diff --git a/crates/bashkit/src/builtins/archive.rs b/crates/bashkit/src/builtins/archive.rs index 1606a98d..bc0b4ff3 100644 --- a/crates/bashkit/src/builtins/archive.rs +++ b/crates/bashkit/src/builtins/archive.rs @@ -165,7 +165,15 @@ impl Builtin for Tar { 2, )); } - create_tar(&ctx, &archive_name, &files, verbose, gzip).await + create_tar( + &ctx, + &archive_name, + &files, + verbose, + gzip, + change_dir.as_deref(), + ) + .await } else if extract { extract_tar( &ctx, @@ -192,12 +200,19 @@ async fn create_tar( files: &[String], verbose: bool, gzip: bool, + change_dir: Option<&str>, ) -> Result { let mut output_data: Vec = Vec::new(); let mut verbose_output = String::new(); + let base_dir = if let Some(dir) = change_dir { + resolve_path(ctx.cwd, dir) + } else { + ctx.cwd.clone() + }; + for file in files { - let path = resolve_path(ctx.cwd, file); + let path = resolve_path(&base_dir, file); if !ctx.fs.exists(&path).await.unwrap_or(false) { return Ok(ExecResult::err( diff --git a/crates/bashkit/tests/spec_cases/bash/tar_create.test.sh b/crates/bashkit/tests/spec_cases/bash/tar_create.test.sh new file mode 100644 index 00000000..6793d067 --- /dev/null +++ b/crates/bashkit/tests/spec_cases/bash/tar_create.test.sh @@ -0,0 +1,29 @@ +# tar create tests +# Tests tar -c with VFS files and -C flag (issue #1118) + +### tar_create_basic +# tar -c creates an archive from VFS files +echo "content" > /tmp/test.txt +tar -c -f /tmp/test.tar /tmp/test.txt +test -f /tmp/test.tar && echo "archive created" +### expect +archive created +### end + +### tar_create_with_C_flag +# tar -c -C resolves files relative to the given directory +echo "hello" > /tmp/file.txt +tar -c -f /tmp/out.tar -C /tmp file.txt +test -f /tmp/out.tar && echo "archive created" +### expect +archive created +### end + +### tar_create_gzip +# tar -czf creates a gzip archive +echo "data" > /tmp/gz.txt +tar -c -z -f /tmp/gz.tar.gz -C /tmp gz.txt +test -f /tmp/gz.tar.gz && echo "archive created" +### expect +archive created +### end diff --git a/crates/bashkit/tests/threat_model_tests.rs b/crates/bashkit/tests/threat_model_tests.rs index 3f89c557..55ce8227 100644 --- a/crates/bashkit/tests/threat_model_tests.rs +++ b/crates/bashkit/tests/threat_model_tests.rs @@ -2404,7 +2404,7 @@ mod archive_security { /// TM-DOS-008: Tar with many files — FS file count limit blocks extraction #[tokio::test] async fn threat_tar_bomb_many_files_blocked() { - let limits = FsLimits::new().max_file_count(20); + let limits = FsLimits::new().max_file_count(30); let fs = Arc::new(InMemoryFs::with_limits(limits)); let mut bash = Bash::builder().fs(fs).build();