From b6ccc2713c19ac9f48f611e206d37520dbb5620b Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 28 Feb 2024 17:41:43 +0100 Subject: [PATCH] fix: segfault on long paths --- api/src/npm/tarball.rs | 9 ++++++++- api/src/publish.rs | 10 ++++++++++ ...n_the_rust_tar_crate_exceeding_one_hundred_bytes.ts | 10 ++++++++++ api/testdata/tarballs/no_long_paths/jsr.json | 5 +++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 api/testdata/tarballs/no_long_paths/a_very_long_filename_created_specifically_to_test_the_limitations_of_the_set_path_method_in_the_rust_tar_crate_exceeding_one_hundred_bytes.ts create mode 100644 api/testdata/tarballs/no_long_paths/jsr.json diff --git a/api/src/npm/tarball.rs b/api/src/npm/tarball.rs index 229b61b7..eecb8755 100644 --- a/api/src/npm/tarball.rs +++ b/api/src/npm/tarball.rs @@ -175,7 +175,14 @@ pub fn create_npm_tarball<'a>( for (path, content) in transpiled_files.iter() { let mut header = Header::new_gnu(); - header.set_path(format!("./package{path}")).unwrap(); + header.set_path(format!("./package{path}")).map_err(|_e| { + // TODO(ry): Currently this PublishError is swallowed and turned into + // NpmTarballError. Change error type of this function to PublishError. + crate::tarball::PublishError::InvalidPath { + path: path.to_string(), + error: crate::ids::PackagePathValidationError::TooLong(path.len()), + } + })?; header.set_size(content.len() as u64); header.set_mode(0o777); header.set_mtime(mtime); diff --git a/api/src/publish.rs b/api/src/publish.rs index 328ae69a..fc08c2e6 100644 --- a/api/src/publish.rs +++ b/api/src/publish.rs @@ -1012,6 +1012,16 @@ pub mod tests { assert_eq!(error.code, "missingConfigFile"); } + #[tokio::test] + async fn no_long_paths() { + let t = TestSetup::new().await; + let bytes = create_mock_tarball("no_long_paths"); + let task = process_tarball_setup(&t, bytes).await; + assert_eq!(task.status, PublishingTaskStatus::Failure, "{task:#?}"); + let error = task.error.unwrap(); + assert_eq!(error.code, "npmTarballError"); + } + #[tokio::test] async fn global_type_augmentation1() { let t = TestSetup::new().await; diff --git a/api/testdata/tarballs/no_long_paths/a_very_long_filename_created_specifically_to_test_the_limitations_of_the_set_path_method_in_the_rust_tar_crate_exceeding_one_hundred_bytes.ts b/api/testdata/tarballs/no_long_paths/a_very_long_filename_created_specifically_to_test_the_limitations_of_the_set_path_method_in_the_rust_tar_crate_exceeding_one_hundred_bytes.ts new file mode 100644 index 00000000..d1e444a9 --- /dev/null +++ b/api/testdata/tarballs/no_long_paths/a_very_long_filename_created_specifically_to_test_the_limitations_of_the_set_path_method_in_the_rust_tar_crate_exceeding_one_hundred_bytes.ts @@ -0,0 +1,10 @@ +/** + * This is a test module. + * + * @module + */ + +/** + * This is a test constant. + */ +export const hello = "Hello, world!"; diff --git a/api/testdata/tarballs/no_long_paths/jsr.json b/api/testdata/tarballs/no_long_paths/jsr.json new file mode 100644 index 00000000..f91fa1c3 --- /dev/null +++ b/api/testdata/tarballs/no_long_paths/jsr.json @@ -0,0 +1,5 @@ +{ + "name": "@scope/foo", + "version": "1.2.3", + "exports": "./a_very_long_filename_created_specifically_to_test_the_limitations_of_the_set_path_method_in_the_rust_tar_crate_exceeding_one_hundred_bytes.ts" +}