diff options
| -rw-r--r-- | llvm/lib/Object/Archive.cpp | 28 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-objdump/malformed-archives.test | 60 |
2 files changed, 73 insertions, 15 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp index c866c407d48..c509124d9be 100644 --- a/llvm/lib/Object/Archive.cpp +++ b/llvm/lib/Object/Archive.cpp @@ -45,15 +45,15 @@ ArchiveMemberHeader::ArchiveMemberHeader(const Archive *Parent, if (Size < sizeof(ArMemHdrType)) { if (Err) { - Twine Msg("remaining size of archive too small for next archive member " - "header "); + std::string Msg("remaining size of archive too small for next archive " + "member header "); Expected<StringRef> NameOrErr = getName(Size); if (!NameOrErr) { consumeError(NameOrErr.takeError()); uint64_t Offset = RawHeaderPtr - Parent->getData().data(); *Err = malformedError(Msg + "at offset " + Twine(Offset)); } else - *Err = malformedError(Msg + "for " + Twine(NameOrErr.get())); + *Err = malformedError(Msg + "for " + NameOrErr.get()); } return; } @@ -64,15 +64,16 @@ ArchiveMemberHeader::ArchiveMemberHeader(const Archive *Parent, OS.write_escaped(llvm::StringRef(ArMemHdr->Terminator, sizeof(ArMemHdr->Terminator))); OS.flush(); - Twine Msg("terminator characters in archive member \"" + Buf + "\" not " - "the correct \"`\\n\" values for the archive member header "); + std::string Msg("terminator characters in archive member \"" + Buf + + "\" not the correct \"`\\n\" values for the archive " + "member header "); Expected<StringRef> NameOrErr = getName(Size); if (!NameOrErr) { consumeError(NameOrErr.takeError()); uint64_t Offset = RawHeaderPtr - Parent->getData().data(); *Err = malformedError(Msg + "at offset " + Twine(Offset)); } else - *Err = malformedError(Msg + "for " + Twine(NameOrErr.get())); + *Err = malformedError(Msg + "for " + NameOrErr.get()); } return; } @@ -139,8 +140,7 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const { if (Name.substr(1).rtrim(' ').getAsInteger(10, StringOffset)) { std::string Buf; raw_string_ostream OS(Buf); - OS.write_escaped(Name.substr(1).rtrim(' '), - sizeof(Name.substr(1)).rtrim(' ')); + OS.write_escaped(Name.substr(1).rtrim(' ')); OS.flush(); uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data(); @@ -172,8 +172,7 @@ Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const { if (Name.substr(3).rtrim(' ').getAsInteger(10, NameLength)) { std::string Buf; raw_string_ostream OS(Buf); - OS.write_escaped(Name.substr(3).rtrim(' '), - sizeof(Name.substr(3)).rtrim(' ')); + OS.write_escaped(Name.substr(3).rtrim(' ')); OS.flush(); uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data(); @@ -316,8 +315,7 @@ Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err) if (Err) { std::string Buf; raw_string_ostream OS(Buf); - OS.write_escaped(Name.substr(3).rtrim(' '), - sizeof(Name.substr(3)).rtrim(' ')); + OS.write_escaped(Name.substr(3).rtrim(' ')); OS.flush(); uint64_t Offset = Start - Parent->getData().data(); *Err = malformedError("long name length characters after the #1/ are " @@ -407,15 +405,15 @@ Expected<Archive::Child> Archive::Child::getNext() const { // Check to see if this is past the end of the archive. if (NextLoc > Parent->Data.getBufferEnd()) { - Twine Msg("offset to next archive member past the end of the archive after " - "member "); + std::string Msg("offset to next archive member past the end of the archive " + "after member "); Expected<StringRef> NameOrErr = getName(); if (!NameOrErr) { consumeError(NameOrErr.takeError()); uint64_t Offset = Data.data() - Parent->getData().data(); return malformedError(Msg + "at offset " + Twine(Offset)); } else - return malformedError(Msg + Twine(NameOrErr.get())); + return malformedError(Msg + NameOrErr.get()); } Error Err; diff --git a/llvm/test/tools/llvm-objdump/malformed-archives.test b/llvm/test/tools/llvm-objdump/malformed-archives.test new file mode 100644 index 00000000000..a9733d5939d --- /dev/null +++ b/llvm/test/tools/llvm-objdump/malformed-archives.test @@ -0,0 +1,60 @@ +// These test checks that llvm-objdump will not crash with malformed Archive +// files. So the check line is not all that important but the bug fixes to +// make sure llvm-objdump is robust is what matters. +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus1.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus1 %s + +# bogus1: libbogus1.a': truncated or malformed archive (characters in size field in archive header are not all decimal numbers: '10%' for archive member header at offset 8) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus2.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus2 %s + +# bogus2: libbogus2.a': truncated or malformed archive (characters in size field in archive header are not all decimal numbers: '1%' for archive member header at offset 170) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus3.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus3 %s + +# bogus3: libbogus3.a': truncated or malformed archive (offset to next archive member past the end of the archive after member foo.c) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus4.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus4 %s + +# bogus4: libbogus4.a': truncated or malformed archive (remaining size of archive too small for next archive member header for foo.c) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus5.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus5 %s + +# bogus5: libbogus5.a': truncated or malformed archive (terminator characters in archive member "@\n" not the correct "`\n" values for the archive member header for hello.c) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus6.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus6 %s + +# bogus6: libbogus6.a': truncated or malformed archive (name contains a leading space for archive member header at offset 96) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus7.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus7 %s + +# bogus7: libbogus7.a': truncated or malformed archive (long name length characters after the #1/ are not all decimal numbers: '@123$' for archive member header at offset 8) + +# RUN: not llvm-objdump -macho -archive-headers \ +# RUN: %p/Inputs/libbogus8.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus8 %s + +# bogus8: libbogus8.a(???) truncated or malformed archive (long name length: 1234 extends past the end of the member or archive for archive member header at offset 86) + +# RUN: not llvm-objdump -s %p/Inputs/libbogus9.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus9 %s + +# bogus9: libbogus9.a(???) truncated or malformed archive (long name offset characters after the '/' are not all decimal numbers: '&a25*' for archive member header at offset 94) + +# RUN: not llvm-objdump -s %p/Inputs/libbogus10.a \ +# RUN: 2>&1 | FileCheck -check-prefix=bogus10 %s + +# bogus10: libbogus10.a(???) truncated or malformed archive (long name offset 507 past the end of the string table for archive member header at offset 94) |

