-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check *all* errors in LLVMRustArchiveIterator* API #38676
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
cc @dylanmckay @shepmaster |
// that complicates the API. | ||
// As a broken archive is bad news anyway, let's just return NULL | ||
// "one child too soon". | ||
#ifdef LLVM_VERSION_GE(3, 9) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be #if
, right?
Also, if this branch is taken, that should free ret
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, yes.
Could we perhaps tweak this to check errors at the appropriate time instead? That is, only advance the cursor on calls to |
We do only advance the cursor when calling |
Oh right yeah what I mean is that we only advance the internal iterator when we need to actually fetch the result of the advance. I think we could store some boolean flags or something like that to avoid skipping the first child, right? |
That would be pretty icky, but so is this hack. I'll give it a shot. |
9883a01
to
c99d716
Compare
@alexcrichton Updated. |
return NULL; | ||
} | ||
|
||
if (rai->cur == rai->end) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should happen first to prevent a segfault from calling next
too much, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yeah, it should be above as well, but it's needed here, too (I got segfaults without it).
} | ||
const Archive::Child &child = cur->get(); | ||
#else | ||
const Archive::Child &child = *rai->cur.operator->(); | ||
#endif | ||
Archive::Child *ret = new Archive::Child(child); | ||
|
||
++rai->cur; | ||
rai->first = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could go in an else
above with the check to ensure it always happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea!
c99d716
to
f4f2b2e
Compare
Incrementing the `Archive::child_iterator` fetches and validates the next child. This can trigger an error, which we previously checked on the *next* call to `LLVMRustArchiveIteratorNext()`. This means we ignore the last error if we stop iterating halfway through. This is harmless (we don't access the child, after all) but LLVM 4.0 calls `abort()` if *any* error goes unchecked, even a success value. This means that basically any rustc invocation that opens an archive and searches through it would die. The solution implemented here is to change the order of operations, such that advancing the iterator and fetching the newly-validated iterator happens in the same `Next()` call. This keeps the error handling behavior as before but ensures all `Error`s get checked.
f4f2b2e
to
8d50857
Compare
Updated. |
@bors: r+ Thanks! |
📌 Commit 8d50857 has been approved by |
…richton Check *all* errors in LLVMRustArchiveIterator* API Incrementing the `Archive::child_iterator` fetches and validates the next child. This can trigger an error, which we previously checked on the *next* call to `LLVMRustArchiveIteratorNext()`. This means we ignore the last error if we stop iterating halfway through. This is harmless (we don't access the child, after all) but LLVM 4.0 calls `abort()` if *any* error goes unchecked, even a success value. This means that basically any rustc invocation that opens an archive and searches through it would die. The solution implemented here is to change the order of operations, such that advancing the iterator and fetching the newly-validated iterator happens in the same `Next()` call. This keeps the error handling behavior as before but ensures all `Error`s get checked.
Incrementing the
Archive::child_iterator
fetches and validates the next child.This can trigger an error, which we previously checked on the next call to
LLVMRustArchiveIteratorNext()
.This means we ignore the last error if we stop iterating halfway through.
This is harmless (we don't access the child, after all) but LLVM 4.0 calls
abort()
if any error goes unchecked, even a success value.This means that basically any rustc invocation that opens an archive and searches through it would die.
The solution implemented here is to change the order of operations, such that
advancing the iterator and fetching the newly-validated iterator happens in the same
Next()
call.This keeps the error handling behavior as before but ensures all
Error
s get checked.