Skip to content

fix(arrow-string): reject FixedSizeBinary concat widths that overflow i32 - #10981

Merged
Jefffrey merged 2 commits into
apache:mainfrom
Cintu07:fix/concat-fixed-size-binary-width-overflow
Sep 4, 2026
Merged

fix(arrow-string): reject FixedSizeBinary concat widths that overflow i32#10981
Jefffrey merged 2 commits into
apache:mainfrom
Cintu07:fix/concat-fixed-size-binary-width-overflow

Conversation

@Cintu07

@Cintu07 Cintu07 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

concat_elements_fixed_size_binary adds the two input widths together as a usize, then casts
the sum to i32 to size the builder. two arrays of width 0x70000000 come out at 3758096384,
which wraps to -536870912, and the builder asserts the value length is not negative. that
width is accepted at array construction and can come from a user controlled schema, so nothing
unusual on the caller's side is needed to reach it

it comes through concat_elements_dyn as well, since that dispatches here for fixed size
binary inputs

What changes are included in this PR?

use i32::try_from on the combined width and return an invalid argument error when it does not
fit, rather than casting

the byte view builder in this same file already guards exactly this, checking data_size
against i32::MAX before it builds, so this is that guard applied to the fixed size binary path
instead of a new mechanism. widths that already fit behave the same as before

i went through the rest of the file for the same shape while i was in there. that cast was the
only unchecked one, so this is a single site rather than a family the way #10437 and #10575
were

one thing i left out on purpose. the next line still reserves the combined width through
MutableBuffer::with_capacity, so a sum just under i32::MAX asks for roughly 2 GB before a
single row is written. that looked like #10973 rather than this one, but say the word and i
will fold it in

Are these changes tested?

yes. test_fixed_size_binary_concat_width_overflow uses the widths from the issue and checks
the call comes back as an error instead of panicking. with only the test applied to current
main it fails inside fixed_size_binary_builder.rs at line 64, which is the panic site in the
report. fmt and clippy with -D warnings are both clean on arrow-string

Are there any user-facing changes?

concatenating two fixed size binary arrays whose widths sum past i32::MAX returns an error now
instead of panicking. no API changes

… i32

concat_elements_fixed_size_binary summed the two input widths into a
usize and then cast that sum to i32 when sizing the builder. Two arrays
of width 0x70000000 give an output width of 3758096384, which wraps to
-536870912, and FixedSizeBinaryBuilder asserts the length is not
negative. The width can come from a user controlled schema, so the
process aborted instead of returning an error.

ConcatByteViewBuilder in the same file already guards this by checking
data_size against i32::MAX before building, so do the same here and
return InvalidArgumentError. Widths that already worked are unaffected.
Copilot AI lite review requested due to automatic review settings September 4, 2026 08:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added arrow Changes to the arrow crate arrow-string labels Sep 4, 2026
Comment thread arrow-string/src/concat_elements.rs Outdated
Comment on lines +224 to +225
"Concatenated FixedSizeBinary value length {output_size} exceeds {}",
i32::MAX

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Concatenated FixedSizeBinary value length {output_size} exceeds {}",
i32::MAX
"Concatenated FixedSizeBinary value length exceeds i32",

those big numbers arent really readable so not sure how useful they would be in the error

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah fair, 2147483647 reads as noise.

heads up though, the test asserts the whole string so the suggestion alone reds ci.
i'll fix test_fixed_size_binary_concat_width_overflow in the same commit either way.

only bit i'd keep is {output_size}, that one's the caller's own width not a constant,
so it says which pair blew up when it comes through concat_elements_dyn. so
"value length {output_size} exceeds i32". happy to take yours as written though, say
which and i'll push.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds reasonable

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed in 7a3b559. kept {output_size} and dropped the constant. if you prefer your
version as written, let me know and i will push that instead.

@Jefffrey Jefffrey added the bug label Sep 4, 2026
The limit was interpolated from i32::MAX, which renders as a bare
2147483647 and does not read as a type bound. Name the type instead and
keep the offending combined width, which is the caller's own value and
identifies which pair of arrays tripped it.
@Jefffrey
Jefffrey merged commit 22327cb into apache:main Sep 4, 2026
33 checks passed
@Jefffrey

Jefffrey commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

thanks for this @Cintu07

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow Changes to the arrow crate arrow-string bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

concat_elements_fixed_size_binary panics / over-allocates on untrusted FixedSizeBinary widths

3 participants