diff --git a/src/dwarfs/global_entry_data.cpp b/src/dwarfs/global_entry_data.cpp index 1f762a0b..b7f2d4c7 100644 --- a/src/dwarfs/global_entry_data.cpp +++ b/src/dwarfs/global_entry_data.cpp @@ -36,11 +36,13 @@ std::vector global_entry_data::get_vector(map_type const& map) const { } auto global_entry_data::get_uids() const -> std::vector { - return get_vector(uids_); + return options_.uid ? std::vector{*options_.uid} + : get_vector(uids_); } auto global_entry_data::get_gids() const -> std::vector { - return get_vector(gids_); + return options_.gid ? std::vector{*options_.gid} + : get_vector(gids_); } auto global_entry_data::get_modes() const -> std::vector { @@ -85,11 +87,11 @@ uint64_t global_entry_data::get_timestamp_base() const { } size_t global_entry_data::get_uid_index(uid_type uid) const { - return options_.uid ? *options_.uid : DWARFS_NOTHROW(uids_.at(uid)); + return options_.uid ? 0 : DWARFS_NOTHROW(uids_.at(uid)); } size_t global_entry_data::get_gid_index(gid_type gid) const { - return options_.gid ? *options_.gid : DWARFS_NOTHROW(gids_.at(gid)); + return options_.gid ? 0 : DWARFS_NOTHROW(gids_.at(gid)); } size_t global_entry_data::get_mode_index(mode_type mode) const { diff --git a/src/dwarfs/metadata_types.cpp b/src/dwarfs/metadata_types.cpp index 7a452465..a7f84333 100644 --- a/src/dwarfs/metadata_types.cpp +++ b/src/dwarfs/metadata_types.cpp @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -540,6 +541,7 @@ uint32_t global_metadata::parent_dir_entry(uint32_t ino) const { } auto inode_view::mode() const -> mode_type { + assert(mode_index() < meta_->modes().size()); return meta_->modes()[mode_index()]; } @@ -552,10 +554,18 @@ auto inode_view::perm_string() const -> std::string { } auto inode_view::getuid() const -> uid_type { + if (meta_->uids().empty()) { + return 0; + } + assert(owner_index() < meta_->uids().size()); return meta_->uids()[owner_index()]; } auto inode_view::getgid() const -> gid_type { + if (meta_->gids().empty()) { + return 0; + } + assert(group_index() < meta_->gids().size()); return meta_->gids()[group_index()]; } diff --git a/test/tool_main_test.cpp b/test/tool_main_test.cpp index 5a2a2ded..552c11de 100644 --- a/test/tool_main_test.cpp +++ b/test/tool_main_test.cpp @@ -191,16 +191,16 @@ class mkdwarfs_tester { std::unique_ptr lgr; }; -std::optional +std::tuple, mkdwarfs_tester> build_with_args(std::vector opt_args = {}) { std::string const image_file = "test.dwarfs"; mkdwarfs_tester t; std::vector args = {"-i", "/", "-o", image_file}; args.insert(args.end(), opt_args.begin(), opt_args.end()); if (t.run(args) != 0) { - return std::nullopt; + return {std::nullopt, std::move(t)}; } - return t.fs_from_file(image_file); + return {t.fs_from_file(image_file), std::move(t)}; } std::set get_all_fs_times(filesystem_v2 const& fs) { @@ -215,6 +215,26 @@ std::set get_all_fs_times(filesystem_v2 const& fs) { return times; } +std::set get_all_fs_uids(filesystem_v2 const& fs) { + std::set uids; + fs.walk([&](auto const& e) { + file_stat st; + fs.getattr(e.inode(), &st); + uids.insert(st.uid); + }); + return uids; +} + +std::set get_all_fs_gids(filesystem_v2 const& fs) { + std::set gids; + fs.walk([&](auto const& e) { + file_stat st; + fs.getattr(e.inode(), &st); + gids.insert(st.gid); + }); + return gids; +} + } // namespace class mkdwarfs_main_test : public tool_main_test { @@ -527,12 +547,12 @@ TEST(mkdwarfs_test, set_time_now) { auto t0 = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - auto regfs = build_with_args(); - ASSERT_TRUE(regfs); + auto [regfs, regt] = build_with_args(); + ASSERT_TRUE(regfs) << regt.err(); auto reg = get_all_fs_times(*regfs); - auto optfs = build_with_args({"--set-time=now"}); - ASSERT_TRUE(optfs); + auto [optfs, optt] = build_with_args({"--set-time=now"}); + ASSERT_TRUE(optfs) << optt.err(); auto opt = get_all_fs_times(*optfs); auto t1 = @@ -546,12 +566,12 @@ TEST(mkdwarfs_test, set_time_now) { } TEST(mkdwarfs_test, set_time_epoch) { - auto regfs = build_with_args(); - ASSERT_TRUE(regfs); + auto [regfs, regt] = build_with_args(); + ASSERT_TRUE(regfs) << regt.err(); auto reg = get_all_fs_times(*regfs); - auto optfs = build_with_args({"--set-time=100000001"}); - ASSERT_TRUE(optfs); + auto [optfs, optt] = build_with_args({"--set-time=100000001"}); + ASSERT_TRUE(optfs) << optt.err(); auto opt = get_all_fs_times(*optfs); EXPECT_EQ(reg.size(), 11); @@ -564,8 +584,8 @@ TEST(mkdwarfs_test, set_time_epoch_string) { using namespace std::chrono_literals; using std::chrono::sys_days; - auto optfs = build_with_args({"--set-time", "2020-01-01 01:02"}); - ASSERT_TRUE(optfs); + auto [optfs, optt] = build_with_args({"--set-time", "2020-01-01 01:02"}); + ASSERT_TRUE(optfs) << optt.err(); auto opt = get_all_fs_times(*optfs); ASSERT_EQ(opt.size(), 1); @@ -582,6 +602,36 @@ TEST(mkdwarfs_test, set_time_error) { EXPECT_THAT(t.err(), ::testing::HasSubstr("cannot parse time point")); } +TEST(mkdwarfs_test, set_owner) { + auto [regfs, regt] = build_with_args(); + ASSERT_TRUE(regfs) << regt.err(); + auto reg = get_all_fs_uids(*regfs); + + auto [optfs, optt] = build_with_args({"--set-owner=333"}); + ASSERT_TRUE(optfs) << optt.err(); + auto opt = get_all_fs_uids(*optfs); + + ASSERT_EQ(reg.size(), 2); + ASSERT_EQ(opt.size(), 1); + + EXPECT_EQ(*opt.begin(), 333); +} + +TEST(mkdwarfs_test, set_group) { + auto [regfs, regt] = build_with_args(); + ASSERT_TRUE(regfs) << regt.err(); + auto reg = get_all_fs_gids(*regfs); + + auto [optfs, optt] = build_with_args({"--set-group=444"}); + ASSERT_TRUE(optfs) << optt.err(); + auto opt = get_all_fs_gids(*optfs); + + ASSERT_EQ(reg.size(), 2); + ASSERT_EQ(opt.size(), 1); + + EXPECT_EQ(*opt.begin(), 444); +} + TEST(mkdwarfs_test, unrecognized_arguments) { auto t = mkdwarfs_tester::create_empty(); EXPECT_NE(0, t.run({"grmpf"}));