Skip to content

Validate Array offsets when loading from the wire - #580

Open
iliaal wants to merge 1 commit into
ClickHouse:masterfrom
iliaal:fix/array-offsets-monotonic
Open

iliaal wants to merge 1 commit into
ClickHouse:masterfrom
iliaal:fix/array-offsets-monotonic

Conversation

@iliaal

@iliaal iliaal commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

The ColumnArray constructor rejects decreasing offsets and a nested column whose size differs from the last offset, but ColumnArray::LoadBody checks neither. With decreasing offsets from the server, GetSize() and GetAsColumn() compute offsets[n] - offsets[n - 1] with unsigned wraparound. For Array(Nothing), whose Slice() keeps any length, a row then reports a length near 2^64.

Fix: LoadBody throws ProtocolError on a decreasing offset, and when the nested column doesn't hold exactly as many values as the last offset. When there are no rows, or every array is empty, it clears the stale nested values instead of returning early, so a reused column keeps the same invariant.

Reproducer: an Array(Nothing) column with 2 rows and offsets [5, 2]. Another case is Array(FixedString(N)), where N times the row count wraps, with offsets [4]: the nested column then holds 0 values instead of 4.

Tests: ColumnArray.Load_DecreasingOffsets, Load_NestedSizeMismatch, Load_FixedStringNestedSizeMismatch and Load_ReplacesPreviousRows fail on master. Valid-offset and empty-array controls pass on both.

The ColumnArray constructor rejects decreasing offsets and a nested column
whose size differs from the last offset, but ColumnArray::LoadBody checked
neither. With decreasing offsets from the server, GetSize() and GetAsColumn()
computed offsets[n] - offsets[n - 1] with unsigned wraparound; for
Array(Nothing), whose Slice() keeps any length, a row then reported a length
near 2^64.

LoadBody now throws a ProtocolError on a decreasing offset and when the
nested column does not hold exactly as many values as the last offset. When
there are no rows or every array is empty it clears the stale nested values
instead of returning early, so a reused column keeps that invariant too.
@iliaal
iliaal requested review from mzitnik and slabko as code owners October 18, 2026 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant