Uh oh!
There was an error while loading. Please reload this page.
GH-49740: [C++][Python] Fix casts to view types leaving null variadic buffers - #50166
Conversation
| util::ToInlineBinaryView("hello"), | ||
| util::ToInlineBinaryView("world"), | ||
| }), | ||
| Raises(StatusCode::Invalid)); |
There was a problem hiding this comment.
Can we test the error message somehow?
There was a problem hiding this comment.
Sure, I'll update the tests later.
| nullptr})); | ||
| struct ArrowArray c_export; | ||
| ASSERT_RAISES(Invalid, ExportArray(*arr, &c_export)); |
pitrou
commented
Jun 15, 2026
Hmm, I think we should try to produce some additional columns without any variadic buffers in the integration tests. Are you comfortable doing that @fenfeng9 ? Otherwise I can do it. |
fenfeng9
commented
Jun 15, 2026
Yes, I'm willing to do that. Should I open a new issue for it? |
Or you can do it in this PR, because it would help validate that all implementations are in agreement. |
fenfeng9
commented
Jun 15, 2026
Sounds good, I'll update it in this PR later. Thanks! |
pitrou
commented
Jun 15, 2026
We may want to wait for the outcome of the discussion in #50172, actually |
fenfeng9
commented
Jun 15, 2026
It's OK, I'll update the code after the discussion is concluded. |
pitrou
commented
Jun 25, 2026
Ok, in #50172 the consensus is that null variadic buffers should be allowed, at least when importing from the C Data Interface. So we can either:
|
fenfeng9
commented
Jun 25, 2026
Agree. Then we just need to check for arrow/cpp/src/arrow/c/bridge.cc Lines 606 to 614 in 445851a |
fenfeng9
commented
Jun 25, 2026
I'll update this PR when that documentation PR is merged. |
fenfeng9
commented
Jun 25, 2026
Sorry, it seems we only agreed to allow nullptr variadic buffers for the C Data Interface #50172 , but not for Arrow C++ internally. |
pitrou
commented
Jun 25, 2026
Well, allowing null variadic buffers inside Arrow C++ might lead to hidden issues if we dereference them. Perhaps it's better to normalize null variadic buffers when importing them over the C Data Interface. |
fenfeng9
commented
Jun 25, 2026
It looks like the import path already handles null buffers — when the data pointer is null and size is 0, it gets normalized to
arrow/cpp/src/arrow/c/bridge.cc Lines 1767 to 1774 in 445851a
arrow/cpp/src/arrow/c/bridge.cc Lines 1912 to 1935 in 445851a arrow/cpp/src/arrow/c/bridge.cc Lines 1944 to 1947 in 445851a |
pitrou
commented
Jun 25, 2026
Ok, so this implies we probably don't want to produce null variadic buffers in other Arrow functionality (such as casting to binary-view). |
pitrou
commented
Jun 25, 2026
Also, we need to add tests for null variadic buffers in |
fenfeng9
commented
Jun 25, 2026
Okay, so we keep the other changes? The And do we also need to update other documentation to state that we do not allow generating null variadic buffers? |
fenfeng9
commented
Jun 25, 2026
I will update pr later. |
pitrou
commented
Jun 25, 2026
Yes, I think validation should still reject them.
I don't think we have a piece of documentation that covers this, do we? |
fenfeng9
commented
Jun 25, 2026
No, there isn't. Thanks for the patient reply. Now I understand: we don't generate null variadic buffers inside Arrow C++. |
9c8b268 to
d889932Comparefenfeng9
commented
Jun 26, 2026
CI failures seems unrelated to this PR:
|
fenfeng9
commented
Jun 26, 2026
I added |
| size_t i = 0; | ||
| for (const auto& buf : variadic_buffers) { | ||
| export_.variadic_buffer_sizes_[i++] = buf->size(); | ||
| // The C Data Interface allows null variadic buffer pointers with size 0. |
There was a problem hiding this comment.
But they are invalid in Arrow C++, so we can revert this change, or explicitly raise an error if we want to avoid a segfault.
(sorry, I think I said something different about this earlier; but I don't think it makes sense to explicitly allow exporting data that is invalid)
There was a problem hiding this comment.
Agree. We should raise an error on export when the data is invalid.
There was a problem hiding this comment.
Done, export now rejects null variadic buffers with Invalid.
| # Generate only inline values, leaving no variadic data buffers. | ||
| def _random_sizes(self, size): | ||
| return np.arange(size, dtype=np.int32) % (BINARY_VIEW_INLINE_SIZE + 1) |
There was a problem hiding this comment.
There was a problem hiding this comment.
update to np.random.randint
| # Generate only inline values, leaving no variadic data buffers. | ||
| def _random_sizes(self, size): | ||
| return np.arange(size, dtype=np.int32) % (BINARY_VIEW_INLINE_SIZE + 1) |
There was a problem hiding this comment.
fenfeng9
commented
Jun 30, 2026
Sure, I will update pr late. |
d889932 to
474dc3eComparefenfeng9
commented
Jun 30, 2026
One test failed because: |
pitrou
commented
Jul 1, 2026
Yes, feel free to disregard as it's unrelated :) |
pitrou
commented
Jul 1, 2026
Thanks a lot @fenfeng9 . Also, I've checked that the newly generated integration data doesn't contain non-inline views. @Alex-PLACET This adds some integration data, you might want to later check the Sparrow integration tests still pass with it. |
After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit 4bedf49. There were no benchmark performance regressions. 🎉 The full Conbench report has more details. It also includes information about 13 possible false positives for unstable benchmarks that are known to sometimes produce them. |
Rationale for this change
Casting to
binary_vieworstring_viewcould leave a null variadic buffer slot when all values were inline. This could happen for casts frombinary,large_binary,string,large_string, andfixed_size_binary.The C Data Interface exporter reads every variadic buffer to get its size. Because of that, exporting such an array could crash, for example through PyArrow
_export_to_c.Validation also passed for these arrays. For all-inline view arrays, validation never needed to read an out-of-line data buffer.
What changes are included in this PR?
This PR fixes the cast kernels so all-inline view arrays do not keep a null variadic buffer slot.
It also makes validation reject null variadic buffer slots, and makes C Data export return an error instead of crashing.
C++ and Python regression tests cover the cast, validation, and export paths.
Are these changes tested?
Yes.
Are there any user-facing changes?
No.
This PR contains a "Critical Fix" Exporting an all-inline view array through the C Data Interface could crash the process while using only public APIs.
_export_to_csegmentation fault forbinary_viewarray #49740