-
Notifications
You must be signed in to change notification settings - Fork 4.2k
GH-50440: [C++][Gandiva] fix out-of-bounds read in set_error_for_date #50441
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
a393675
0f5c3eb
d7b6264
aac25da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,6 +18,10 @@ | |||||||||||||||||||||||||
| #include <gmock/gmock.h> | ||||||||||||||||||||||||||
| #include <gtest/gtest.h> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #include <cstring> | ||||||||||||||||||||||||||
| #include <memory> | ||||||||||||||||||||||||||
| #include <string> | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #include "arrow/util/logging_internal.h" | ||||||||||||||||||||||||||
| #include "gandiva/execution_context.h" | ||||||||||||||||||||||||||
| #include "gandiva/precompiled/testing.h" | ||||||||||||||||||||||||||
|
|
@@ -59,6 +63,24 @@ TEST(TestTime, TestCastDate) { | |||||||||||||||||||||||||
| EXPECT_EQ(castDATE_date32(1), 86400000); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| TEST(TestTime, TestCastDateInvalidUnterminated) { | ||||||||||||||||||||||||||
| ExecutionContext context; | ||||||||||||||||||||||||||
| int64_t context_ptr = reinterpret_cast<int64_t>(&context); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // The invalid-value error message is built from the raw input pointer. Hold | ||||||||||||||||||||||||||
| // the input in an exactly-sized heap buffer with no trailing NUL so that | ||||||||||||||||||||||||||
| // formatting the error must respect `length` instead of scanning for a NUL; | ||||||||||||||||||||||||||
| // any over-read past the buffer trips AddressSanitizer. | ||||||||||||||||||||||||||
| const char bytes[] = {'1', '9', '7', '2', '2', '2', '2', '2', '2', '2'}; | ||||||||||||||||||||||||||
| const auto length = static_cast<int32_t>(sizeof(bytes)); | ||||||||||||||||||||||||||
| std::unique_ptr<char[]> input(new char[length]); | ||||||||||||||||||||||||||
| std::memcpy(input.get(), bytes, length); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| EXPECT_EQ(castDATE_utf8(context_ptr, input.get(), length), 0); | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we simplify this? I think that this will include
Suggested change
BTW, can we use different numbers instead of multiple
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call, that's cleaner. Switched all three to a std::string with a trailing sentinel and pass length - 1, so the over-read shows up as the sentinel leaking into the message even without ASAN. Used 197201234X for the date one per your suggestion. |
||||||||||||||||||||||||||
| EXPECT_EQ(context.get_error(), "Not a valid date value 1972222222"); | ||||||||||||||||||||||||||
| context.Reset(); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| TEST(TestTime, TestCastTimestamp) { | ||||||||||||||||||||||||||
| ExecutionContext context; | ||||||||||||||||||||||||||
| int64_t context_ptr = reinterpret_cast<int64_t>(&context); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.
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.
It appears that time and timestamp are going through the same code path. Is this so?
If yes, would there be value in adding two more tests for those data types?
p.s. rest of PR looks good to me just need an evaluation of value of additional tests as helper isn't really data type specific.
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.
Yeah, both castTIMESTAMP_utf8 and castTIME_utf8 hit the same set_error_for_date helper, so the fix already covers them. Added a test for each anyway (2000-01-01 24:00:00 for timestamp, 24H00H00 for time) so the over-read path is exercised from all three entry points with an unterminated buffer.