From 984fca1b51d84671adf15c6394fa9989360c8dcf Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Tue, 1 Dec 2020 11:39:11 +0100 Subject: [PATCH] Fix metadata link handling --- src/dwarfs/metadata_v2.cpp | 2 +- src/dwarfs/scanner.cpp | 1 + test/dwarfs.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 13b368f3..298f57db 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -206,7 +206,7 @@ class metadata_ : public metadata_v2::impl { std::string_view link_value(entry_view entry) const { return meta_ - .links()[meta_.link_index()[entry.inode()] - meta_.link_index_offset()]; + .links()[meta_.link_index()[entry.inode() - meta_.link_index_offset()]]; } folly::ByteRange data_; diff --git a/src/dwarfs/scanner.cpp b/src/dwarfs/scanner.cpp index 0d74dc6b..9aa5bdd6 100644 --- a/src/dwarfs/scanner.cpp +++ b/src/dwarfs/scanner.cpp @@ -533,6 +533,7 @@ void scanner_::scan(filesystem_writer& fsw, mv2.links = ge_data.get_links(); mv2.timestamp_base = ge_data.get_timestamp_base(); mv2.chunk_index_offset = first_file_inode; + mv2.link_index_offset = first_link_inode; mv2.block_size = UINT32_C(1) << cfg_.block_size_bits; mv2.total_fs_size = prog.original_size; diff --git a/test/dwarfs.cpp b/test/dwarfs.cpp index 9ebd602d..ae44c72c 100644 --- a/test/dwarfs.cpp +++ b/test/dwarfs.cpp @@ -77,6 +77,7 @@ std::unordered_map statmap{ {"//foo.pl", {S_IFREG | 0600, 1337, 0, 23456}}, {"//ipsum.txt", {S_IFREG | 0644, 1000, 1000, 2000000}}, {"//somedir/ipsum.py", {S_IFREG | 0644, 1000, 1000, 10000}}, + {"//somedir/bad", {S_IFLNK | 0777, 1000, 1000, 6}}, }; } // namespace @@ -87,6 +88,13 @@ class mmap_mock : public mmif { assign(m_data.data(), m_data.size()); } + boost::system::error_code lock(void const*, size_t) override { + return boost::system::error_code(); + } + boost::system::error_code advise(void const*, size_t, int) override { + return boost::system::error_code(); + } + private: const std::string m_data; }; @@ -105,6 +113,7 @@ class os_access_mock : public os_access { ".", "..", "ipsum.py", + "bad", }; return std::make_shared(std::move(files)); @@ -128,6 +137,8 @@ class os_access_mock : public os_access { std::string readlink(const std::string& path, size_t size) const override { if (path == "//somelink" && size == 16) { return "somedir/ipsum.py"; + } else if (path == "//somedir/bad" && size == 6) { + return "../foo"; } throw std::runtime_error("oops"); @@ -216,6 +227,23 @@ void basic_end_to_end_test(const std::string& compressor, ssize_t rv = fs.read(inode, &buf[0], st.st_size, 0); EXPECT_EQ(rv, st.st_size); EXPECT_EQ(std::string(buf.begin(), buf.end()), test::loremipsum(st.st_size)); + + entry = fs.find("/somelink"); + + EXPECT_EQ(fs.getattr(*entry, &st), 0); + EXPECT_EQ(st.st_size, 16); + + std::string link; + EXPECT_EQ(fs.readlink(*entry, &link), 0); + EXPECT_EQ(link, "somedir/ipsum.py"); + + entry = fs.find("/somedir/bad"); + + EXPECT_EQ(fs.getattr(*entry, &st), 0); + EXPECT_EQ(st.st_size, 6); + + EXPECT_EQ(fs.readlink(*entry, &link), 0); + EXPECT_EQ(link, "../foo"); } std::vector const compressions{"null",