Author: Gabriele Mondada Date: 2026-02-28T12:13:18-08:00 New Revision: 5ed875a06cb0a6d543f719ad72df2a1660e42cb9
URL: https://github.com/llvm/llvm-project/commit/5ed875a06cb0a6d543f719ad72df2a1660e42cb9 DIFF: https://github.com/llvm/llvm-project/commit/5ed875a06cb0a6d543f719ad72df2a1660e42cb9.diff LOG: [lldb][lldb-server] Fix zip file lookup ignoring last entry in the zip file (#173966) Command qModuleInfo (GDB server protocol) can be used to request metadata of shared libraries stored in a ZIP archive on the target. This is typically used for retrieving SO files bundled in a APK file on Android. Requesting the last entry in the ZIP file often fails because of a bug in the entry search mechanism. This PR fixes this. NOTES: * The bug appears only if the entry in the zip file has no extra field or comment * This is part on an effort to get lldb working for debugging Swift on Android: https://github.com/swiftlang/llvm-project/issues/10831 Added: lldb/unittests/Host/common/Inputs/zip-test-no-extras.zip Modified: lldb/source/Utility/ZipFile.cpp lldb/unittests/Host/common/CMakeLists.txt lldb/unittests/Host/common/ZipFileResolverTest.cpp Removed: ################################################################################ diff --git a/lldb/source/Utility/ZipFile.cpp b/lldb/source/Utility/ZipFile.cpp index b8ed956cbfcb2..e47c690e65b0d 100644 --- a/lldb/source/Utility/ZipFile.cpp +++ b/lldb/source/Utility/ZipFile.cpp @@ -144,7 +144,7 @@ bool FindFile(lldb::DataBufferSP zip_data, const EocdRecord *eocd, // Sanity check the file name values. auto file_name = reinterpret_cast<const char *>(cd + 1); size_t file_name_length = cd->file_name_length; - if (file_name + file_name_length >= reinterpret_cast<const char *>(eocd) || + if (file_name + file_name_length > reinterpret_cast<const char *>(eocd) || file_name_length == 0) return false; diff --git a/lldb/unittests/Host/common/CMakeLists.txt b/lldb/unittests/Host/common/CMakeLists.txt index 8aa2dfb4e8e1e..3c52f9bf15fbc 100644 --- a/lldb/unittests/Host/common/CMakeLists.txt +++ b/lldb/unittests/Host/common/CMakeLists.txt @@ -12,5 +12,6 @@ add_lldb_unittest(HostCommonTests set(test_inputs zip-test.zip + zip-test-no-extras.zip ) add_unittest_inputs(HostCommonTests "${test_inputs}") diff --git a/lldb/unittests/Host/common/Inputs/zip-test-no-extras.zip b/lldb/unittests/Host/common/Inputs/zip-test-no-extras.zip new file mode 100644 index 0000000000000..f3a75b8817a98 Binary files /dev/null and b/lldb/unittests/Host/common/Inputs/zip-test-no-extras.zip diff er diff --git a/lldb/unittests/Host/common/ZipFileResolverTest.cpp b/lldb/unittests/Host/common/ZipFileResolverTest.cpp index 12aba31411305..58b652f612ca3 100644 --- a/lldb/unittests/Host/common/ZipFileResolverTest.cpp +++ b/lldb/unittests/Host/common/ZipFileResolverTest.cpp @@ -15,12 +15,30 @@ using namespace lldb_private; using namespace llvm; namespace { +struct ZipFileDesc { + std::string zip_name; + std::string lib_path; + size_t lib_offset; + size_t lib_size; +}; + class ZipFileResolverTest : public ::testing::Test { SubsystemRAII<FileSystem> subsystems; }; -std::string TestZipPath() { - FileSpec zip_spec(GetInputFilePath("zip-test.zip")); +std::vector<ZipFileDesc> TestZipFiles() { + return { + // Simple uncompressed zip file, making use of extra fields + {"zip-test.zip", "lib/arm64-v8a/libzip-test.so", 4096, 3600}, + + // Simple uncompressed zip file, where the shared library is the last + // entry, and the entry has no extra field or comment + {"zip-test-no-extras.zip", "lib/arm64-v8a/libzip-test.so", 140, 3600}, + }; +} + +std::string TestZipPath(const ZipFileDesc &desc) { + FileSpec zip_spec(GetInputFilePath(desc.zip_name)); FileSystem::Instance().Resolve(zip_spec); return zip_spec.GetPath(); } @@ -43,7 +61,7 @@ TEST_F(ZipFileResolverTest, ResolveSharedLibraryPathWithNormalFile) { } TEST_F(ZipFileResolverTest, ResolveSharedLibraryPathWithZipMissing) { - const std::string zip_path = TestZipPath(); + const std::string zip_path = TestZipPath(TestZipFiles().at(0)); const FileSpec file_spec(zip_path + "!/lib/arm64-v8a/libmissing.so"); ZipFileResolver::FileKind file_kind; @@ -55,18 +73,20 @@ TEST_F(ZipFileResolverTest, ResolveSharedLibraryPathWithZipMissing) { } TEST_F(ZipFileResolverTest, ResolveSharedLibraryPathWithZipExisting) { - const std::string zip_path = TestZipPath(); - const FileSpec file_spec(zip_path + "!/lib/arm64-v8a/libzip-test.so"); + for (const auto &zip_desc : TestZipFiles()) { + const std::string zip_path = TestZipPath(zip_desc); + const FileSpec file_spec(zip_path + "!/" + zip_desc.lib_path); - ZipFileResolver::FileKind file_kind; - std::string file_path; - lldb::offset_t file_offset; - lldb::offset_t file_size; - ASSERT_TRUE(ZipFileResolver::ResolveSharedLibraryPath( - file_spec, file_kind, file_path, file_offset, file_size)); + ZipFileResolver::FileKind file_kind; + std::string file_path; + lldb::offset_t file_offset; + lldb::offset_t file_size; + ASSERT_TRUE(ZipFileResolver::ResolveSharedLibraryPath( + file_spec, file_kind, file_path, file_offset, file_size)); - EXPECT_EQ(file_kind, ZipFileResolver::FileKind::eFileKindZip); - EXPECT_EQ(file_path, zip_path); - EXPECT_EQ(file_offset, 4096UL); - EXPECT_EQ(file_size, 3600UL); + EXPECT_EQ(file_kind, ZipFileResolver::FileKind::eFileKindZip); + EXPECT_EQ(file_path, zip_path); + EXPECT_EQ(file_offset, zip_desc.lib_offset); + EXPECT_EQ(file_size, zip_desc.lib_size); + } } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
