llvm.org GIT mirror llvm / e5d1578
Reapply "More fixes to get good error messages for bad archives." This reverts commit the revert commit r277627. The build errors mentioned in r277627 were likely caused by an unclean build directory. Sorry for the noise. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277630 91177308-0d34-0410-b5e6-96231b3b80d8 Vedant Kumar 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"