GH-50311: [C++] KeyValueMetadata::Delete returns IndexError instead of crashing due to seg fault#50322
Conversation
|
|
There was a problem hiding this comment.
Pull request overview
This PR fixes a crash in the C++ arrow::KeyValueMetadata::Delete(int64_t index) implementation by adding bounds checking so out-of-range indices return Status::IndexError instead of triggering undefined behavior.
Changes:
- Added an out-of-bounds guard to
KeyValueMetadata::Delete(int64_t)usingARROW_PREDICT_FALSEandstd::cmp_greater_equal. - Returned
Status::IndexErrorwhenindex < 0orindex >= size.
c2efac9 to
046bb2e
Compare
* The Delete function now catches out of bound index and does not throw a segmentation fault. Signed-off-by: OmBiradar <ombiradar04@gmail.com>
046bb2e to
15fb3bf
Compare
|
The above has been a messy PR with me amending the commit mostly due to me being unsure about the exact error message. |
| } | ||
|
|
||
| Status KeyValueMetadata::Delete(int64_t index) { | ||
| if (ARROW_PREDICT_FALSE(index < 0 || std::cmp_greater_equal(index, values_.size()))) { |
There was a problem hiding this comment.
Why std::cmp_greater_equal? Just use the standard comparison operator here.
There was a problem hiding this comment.
The types are int64_t and size_t, so any operator would cast the int64_t to a size_t which retults in negative numbers being converted to extremely large values (>2^31). While even if this happens the logic would work for any case of negative values as index<0 is true, I think this is the general practice for these types of comparisons? based on what I know
There was a problem hiding this comment.
The Arrow codebase generally casts explicitly, i.e. static_cast<int64_t>(values_.size())
There was a problem hiding this comment.
For values_.size() > 2^31 it would overflow and return a -ve int64_t. Tho it's extremely impossible to have so many elments in the first place.
I was just trying to make it secure 😅
There was a problem hiding this comment.
Should I use static_cast<int64_t>? for consistency with the project
@pitrou
There was a problem hiding this comment.
I changed it to static_cast
|
@OmBiradar This is not really a "critical fix" as this is mostly a API usage question (the caller should have checked index bounds accordingly), can you edit the PR description? |
|
@pitrou yes sure, did it. I was unsure about what critical fixes mean, my rational to add it was that a seg fault would be triggered and crash any program. |
|
Forgot to update the tests |
5ecddee to
7acf912
Compare
7acf912 to
3eee41b
Compare
Co-authored-by: Antoine Pitrou <pitrou@free.fr>
3eee41b to
926c6c4
Compare
Signed-off-by: OmBiradar <ombiradar04@gmail.com>
Rationale for this change
The
KeyValueMetadata::Delete(int64_t index)never checked for out of bounds value ofindex, & ifindexwas out of bounds, then a seg fault was thrown by the program and it aborted.What changes are included in this PR?
The
KeyValueMetadata::Delete(int64_t index)now returns a IndexError for out of bounds values ofindexAre these changes tested?
Yes, CI tests pass on my fork
Are there any user-facing changes?
No API changes
KeyValueMetadatagives seg fault while deleting a key #50311