diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 311f1606..db322556 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -611,6 +611,7 @@ class metadata_ final : public metadata_v2::impl { directory_view make_directory_view(inode_view iv) const { // TODO: revisit: is this the way to do it? + DWARFS_CHECK(iv.is_directory(), "not a directory"); return directory_view(iv.inode_num(), global_); } @@ -1488,6 +1489,10 @@ metadata_::find(const char* path) const { const char* next = ::strchr(path, '/'); size_t clen = next ? next - path : ::strlen(path); // Flawfinder: ignore + if (!iv->is_directory()) { + return std::nullopt; + } + iv = find(make_directory_view(*iv), std::string_view(path, clen)); if (!iv) { @@ -1511,6 +1516,10 @@ metadata_::find(int inode, const char* name) const { auto iv = get_entry(inode); if (iv) { + if (!iv->is_directory()) { + return std::nullopt; + } + iv = find(make_directory_view(*iv), std::string_view(name)); } diff --git a/test/dwarfs_test.cpp b/test/dwarfs_test.cpp index 16b732e7..ff129807 100644 --- a/test/dwarfs_test.cpp +++ b/test/dwarfs_test.cpp @@ -1197,3 +1197,24 @@ TEST(section_index_regression, github183) { EXPECT_THROW(filesystem_v2::identify(lgr, mm, idss, 3), dwarfs::runtime_error); } + +TEST(filesystem, find_by_path) { + test::test_logger lgr; + auto input = test::os_access_mock::create_test_instance(); + auto fsimage = build_dwarfs(lgr, input, "null"); + auto mm = std::make_shared(std::move(fsimage)); + + filesystem_v2 fs(lgr, mm); + + std::vector paths; + fs.walk([&](auto e) { paths.emplace_back(e.unix_path()); }); + + EXPECT_GT(paths.size(), 10); + + for (auto const& p : paths) { + auto iv = fs.find(p.c_str()); + ASSERT_TRUE(iv) << p; + EXPECT_FALSE(fs.find(iv->inode_num(), "desktop.ini")) << p; + EXPECT_FALSE(fs.find((p + "/desktop.ini").c_str())) << p; + } +}