llvm.org GIT mirror llvm / d5adfbc
More fixes to get good error messages for bad archives. Fixed the last incorrect uses of llvm_unreachable() in the code which were actually just cases of errors in the input Archives. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277540 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 4 years ago
11 changed file(s) with 183 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
4343 /// Members are not larger than 4GB.
4444 Expected getSize() const;
4545
46 sys::fs::perms getAccessMode() const;
47 sys::TimeValue getLastModified() const;
46 Expected getAccessMode() const;
47 Expected getLastModified() const;
4848 llvm::StringRef getRawLastModified() const {
4949 return StringRef(ArMemHdr->LastModified,
5050 sizeof(ArMemHdr->LastModified)).rtrim(' ');
5151 }
52 unsigned getUID() const;
53 unsigned getGID() const;
52 Expected getUID() const;
53 Expected getGID() const;
5454
5555 // This returns the size of the private struct ArMemHdrType
5656 uint64_t getSizeOf() const {
101101 Expected getName() const;
102102 ErrorOr getFullName() const;
103103 Expected getRawName() const { return Header.getRawName(); }
104 sys::TimeValue getLastModified() const {
104 Expected getLastModified() const {
105105 return Header.getLastModified();
106106 }
107107 StringRef getRawLastModified() const {
108108 return Header.getRawLastModified();
109109 }
110 unsigned getUID() const { return Header.getUID(); }
111 unsigned getGID() const { return Header.getGID(); }
112 sys::fs::perms getAccessMode() const {
110 Expected getUID() const { return Header.getUID(); }
111 Expected getGID() const { return Header.getGID(); }
112 Expected getAccessMode() const {
113113 return Header.getAccessMode();
114114 }
115115 /// \return the size of the archive member without the header or padding.
220220 return Ret;
221221 }
222222
223 sys::fs::perms ArchiveMemberHeader::getAccessMode() const {
223 Expected ArchiveMemberHeader::getAccessMode() const {
224224 unsigned Ret;
225225 if (StringRef(ArMemHdr->AccessMode,
226 sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret))
227 llvm_unreachable("Access mode is not an octal number.");
226 sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret)) {
227 std::string Buf;
228 raw_string_ostream OS(Buf);
229 OS.write_escaped(llvm::StringRef(ArMemHdr->AccessMode,
230 sizeof(ArMemHdr->AccessMode)).rtrim(" "));
231 OS.flush();
232 uint64_t Offset = reinterpret_cast(ArMemHdr) -
233 Parent->getData().data();
234 return malformedError("characters in AccessMode field in archive header "
235 "are not all decimal numbers: '" + Buf + "' for the "
236 "archive member header at offset " + Twine(Offset));
237 }
228238 return static_cast(Ret);
229239 }
230240
231 sys::TimeValue ArchiveMemberHeader::getLastModified() const {
241 Expected ArchiveMemberHeader::getLastModified() const {
232242 unsigned Seconds;
233243 if (StringRef(ArMemHdr->LastModified,
234244 sizeof(ArMemHdr->LastModified)).rtrim(' ')
235 .getAsInteger(10, Seconds))
236 llvm_unreachable("Last modified time not a decimal number.");
245 .getAsInteger(10, Seconds)) {
246 std::string Buf;
247 raw_string_ostream OS(Buf);
248 OS.write_escaped(llvm::StringRef(ArMemHdr->LastModified,
249 sizeof(ArMemHdr->LastModified)).rtrim(" "));
250 OS.flush();
251 uint64_t Offset = reinterpret_cast(ArMemHdr) -
252 Parent->getData().data();
253 return malformedError("characters in LastModified field in archive header "
254 "are not all decimal numbers: '" + Buf + "' for the "
255 "archive member header at offset " + Twine(Offset));
256 }
237257
238258 sys::TimeValue Ret;
239259 Ret.fromEpochTime(Seconds);
240260 return Ret;
241261 }
242262
243 unsigned ArchiveMemberHeader::getUID() const {
263 Expected ArchiveMemberHeader::getUID() const {
244264 unsigned Ret;
245265 StringRef User = StringRef(ArMemHdr->UID, sizeof(ArMemHdr->UID)).rtrim(' ');
246266 if (User.empty())
247267 return 0;
248 if (User.getAsInteger(10, Ret))
249 llvm_unreachable("UID time not a decimal number.");
268 if (User.getAsInteger(10, Ret)) {
269 std::string Buf;
270 raw_string_ostream OS(Buf);
271 OS.write_escaped(User);
272 OS.flush();
273 uint64_t Offset = reinterpret_cast(ArMemHdr) -
274 Parent->getData().data();
275 return malformedError("characters in UID field in archive header "
276 "are not all decimal numbers: '" + Buf + "' for the "
277 "archive member header at offset " + Twine(Offset));
278 }
250279 return Ret;
251280 }
252281
253 unsigned ArchiveMemberHeader::getGID() const {
282 Expected ArchiveMemberHeader::getGID() const {
254283 unsigned Ret;
255284 StringRef Group = StringRef(ArMemHdr->GID, sizeof(ArMemHdr->GID)).rtrim(' ');
256285 if (Group.empty())
257286 return 0;
258 if (Group.getAsInteger(10, Ret))
259 llvm_unreachable("GID time not a decimal number.");
287 if (Group.getAsInteger(10, Ret)) {
288 std::string Buf;
289 raw_string_ostream OS(Buf);
290 OS.write_escaped(Group);
291 OS.flush();
292 uint64_t Offset = reinterpret_cast(ArMemHdr) -
293 Parent->getData().data();
294 return malformedError("characters in GID field in archive header "
295 "are not all decimal numbers: '" + Buf + "' for the "
296 "archive member header at offset " + Twine(Offset));
297 }
260298 return Ret;
261299 }
262300
4646 NewArchiveMember M;
4747 M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
4848 if (!Deterministic) {
49 M.ModTime = OldMember.getLastModified();
50 M.UID = OldMember.getUID();
51 M.GID = OldMember.getGID();
52 M.Perms = OldMember.getAccessMode();
49 Expected ModTimeOrErr = OldMember.getLastModified();
50 if (!ModTimeOrErr)
51 return ModTimeOrErr.takeError();
52 M.ModTime = ModTimeOrErr.get();
53 Expected UIDOrErr = OldMember.getUID();
54 if (!UIDOrErr)
55 return UIDOrErr.takeError();
56 M.UID = UIDOrErr.get();
57 Expected GIDOrErr = OldMember.getGID();
58 if (!GIDOrErr)
59 return GIDOrErr.takeError();
60 M.GID = GIDOrErr.get();
61 Expected AccessModeOrErr = OldMember.getAccessMode();
62 if (!AccessModeOrErr)
63 return AccessModeOrErr.takeError();
64 M.Perms = AccessModeOrErr.get();
5365 }
5466 return std::move(M);
5567 }
0 !
1 hello.c 1444941273 ~97& 0 100644 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
0 !
1 hello.c 1444941273 124 #55! 100644 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
0 !
1 hello.c 1444941273 124 0 Feed 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
0 !
1 hello.c 1foobar273 124 0 100644 102 `
2 #include
3 #include
4 int
5 main()
6 {
7 printf("Hello World\n");
8 return EXIT_SUCCESS;
9 }
5757 # RUN: 2>&1 | FileCheck -check-prefix=bogus10 %s
5858
5959 # 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)
60
61 # RUN: not llvm-objdump -macho -archive-headers \
62 # RUN: %p/Inputs/libbogus11.a \
63 # RUN: 2>&1 | FileCheck -check-prefix=bogus11 %s
64
65 # bogus11: libbogus11.a(hello.c) truncated or malformed archive (characters in UID field in archive header are not all decimal numbers: '~97&' for the archive member header at offset 8)
66
67 # RUN: not llvm-objdump -macho -archive-headers \
68 # RUN: %p/Inputs/libbogus12.a \
69 # RUN: 2>&1 | FileCheck -check-prefix=bogus12 %s
70
71 # bogus12: libbogus12.a(hello.c) truncated or malformed archive (characters in GID field in archive header are not all decimal numbers: '#55!' for the archive member header at offset 8)
72
73 # RUN: not llvm-objdump -macho -archive-headers \
74 # RUN: %p/Inputs/libbogus13.a \
75 # RUN: 2>&1 | FileCheck -check-prefix=bogus13 %s
76
77 # bogus13: libbogus13.a(hello.c) truncated or malformed archive (characters in AccessMode field in archive header are not all decimal numbers: 'Feed' for the archive member header at offset 8)
78
79 # RUN: llvm-objdump -macho -archive-headers %p/Inputs/libbogus14.a \
80 # RUN: 2>&1 | FileCheck -check-prefix=bogus14 %s
81
82 # bogus14: -rw-r--r--124/0 102 (date: "1foobar273" contains non-decimal chars) hello.c
83
84 # RUN: not llvm-ar tv %p/Inputs/libbogus14.a \
85 # RUN: 2>&1 | FileCheck -check-prefix=bogus14a %s
86
87 # bogus14a: truncated or malformed archive (characters in LastModified field in archive header are not all decimal numbers: '1foobar273' for the archive member header at offset 8)
105105 for (auto Child : CurrentArchive->children(Err)) {
106106 if (auto NameOrErr = Child.getName()) {
107107 if (*NameOrErr == Filename) {
108 Expected ModTimeOrErr = Child.getLastModified();
109 if (!ModTimeOrErr)
110 return errorToErrorCode(ModTimeOrErr.takeError());
108111 if (Timestamp != sys::TimeValue::PosixZeroTime() &&
109 Timestamp != Child.getLastModified()) {
112 Timestamp != ModTimeOrErr.get()) {
110113 if (Verbose)
111114 outs() << "\tmember had timestamp mismatch.\n";
112115 continue;
337337 // modification time are also printed.
338338 static void doDisplayTable(StringRef Name, const object::Archive::Child &C) {
339339 if (Verbose) {
340 sys::fs::perms Mode = C.getAccessMode();
340 Expected ModeOrErr = C.getAccessMode();
341 failIfError(ModeOrErr.takeError());
342 sys::fs::perms Mode = ModeOrErr.get();
341343 printMode((Mode >> 6) & 007);
342344 printMode((Mode >> 3) & 007);
343345 printMode(Mode & 007);
344 outs() << ' ' << C.getUID();
345 outs() << '/' << C.getGID();
346 Expected UIDOrErr = C.getUID();
347 failIfError(UIDOrErr.takeError());
348 outs() << ' ' << UIDOrErr.get();
349 Expected GIDOrErr = C.getGID();
350 failIfError(GIDOrErr.takeError());
351 outs() << '/' << GIDOrErr.get();
346352 Expected Size = C.getSize();
347353 failIfError(Size.takeError());
348354 outs() << ' ' << format("%6llu", Size.get());
349 outs() << ' ' << C.getLastModified().str();
355 Expected ModTimeOrErr = C.getLastModified();
356 failIfError(ModTimeOrErr.takeError());
357 outs() << ' ' << ModTimeOrErr.get().str();
350358 outs() << ' ';
351359 }
352360 outs() << Name << "\n";
356364 // system.
357365 static void doExtract(StringRef Name, const object::Archive::Child &C) {
358366 // Retain the original mode.
359 sys::fs::perms Mode = C.getAccessMode();
367 Expected ModeOrErr = C.getAccessMode();
368 failIfError(ModeOrErr.takeError());
369 sys::fs::perms Mode = ModeOrErr.get();
360370
361371 int FD;
362372 failIfError(sys::fs::openFileForWrite(Name, FD, sys::fs::F_None, Mode), Name);
373383
374384 // If we're supposed to retain the original modification times, etc. do so
375385 // now.
376 if (OriginalDates)
386 if (OriginalDates) {
387 Expected ModTimeOrErr = C.getLastModified();
388 failIfError(ModTimeOrErr.takeError());
377389 failIfError(
378 sys::fs::setLastModificationAndAccessTime(FD, C.getLastModified()));
390 sys::fs::setLastModificationAndAccessTime(FD, ModTimeOrErr.get()));
391 }
379392
380393 if (close(FD))
381394 fail("Could not close the file");
510523 // operation.
511524 sys::fs::file_status Status;
512525 failIfError(sys::fs::status(*MI, Status), *MI);
513 if (Status.getLastModificationTime() < Member.getLastModified()) {
526 Expected ModTimeOrErr = Member.getLastModified();
527 failIfError(ModTimeOrErr.takeError());
528 if (Status.getLastModificationTime() < ModTimeOrErr.get()) {
514529 if (PosName.empty())
515530 return IA_AddOldMember;
516531 return IA_MoveOldMember;
14761476 StringRef ArchitectureName = StringRef()) {
14771477 if (print_offset)
14781478 outs() << C.getChildOffset() << "\t";
1479 sys::fs::perms Mode = C.getAccessMode();
1479 Expected ModeOrErr = C.getAccessMode();
1480 if (!ModeOrErr)
1481 report_error(Filename, C, ModeOrErr.takeError(), ArchitectureName);
1482 sys::fs::perms Mode = ModeOrErr.get();
14801483 if (verbose) {
14811484 // FIXME: this first dash, "-", is for (Mode & S_IFMT) == S_IFREG.
14821485 // But there is nothing in sys::fs::perms for S_IFMT or S_IFREG.
14941497 outs() << format("0%o ", Mode);
14951498 }
14961499
1497 unsigned UID = C.getUID();
1500 Expected UIDOrErr = C.getUID();
1501 if (!UIDOrErr)
1502 report_error(Filename, C, UIDOrErr.takeError(), ArchitectureName);
1503 unsigned UID = UIDOrErr.get();
14981504 outs() << format("%3d/", UID);
1499 unsigned GID = C.getGID();
1505 Expected GIDOrErr = C.getGID();
1506 if (!GIDOrErr)
1507 report_error(Filename, C, GIDOrErr.takeError(), ArchitectureName);
1508 unsigned GID = GIDOrErr.get();
15001509 outs() << format("%-3d ", GID);
15011510 Expected Size = C.getRawSize();
15021511 if (!Size)
15071516 if (verbose) {
15081517 unsigned Seconds;
15091518 if (RawLastModified.getAsInteger(10, Seconds))
1510 outs() << "(date: \"%s\" contains non-decimal chars) " << RawLastModified;
1519 outs() << "(date: \"" << RawLastModified
1520 << "\" contains non-decimal chars) ";
15111521 else {
15121522 // Since cime(3) returns a 26 character string of the form:
15131523 // "Sun Sep 16 01:03:52 1973\n\0"