Skip to content

Fix reverse secondary-index scans over an inverted range - #644

Merged
heifner merged 1 commit into
masterfrom
fix/secondary-reverse-inverted-range
Sep 25, 2026
Merged

heifner merged 1 commit into
masterfrom
fix/secondary-reverse-inverted-range

Conversation

@heifner

@heifner heifner commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

A reverse get_table_rows on a secondary index with upper_bound below lower_bound started its scan below its own stopping point. When the queried table's partition comes first in the chain's secondary index (true of whichever contract account sorts lowest), the scan's first step decremented the index's begin(). That is undefined behavior any API caller could trigger:

clio get table 1secrev users --index byowner -r -L '{"byowner":"u4"}' -U '{"byowner":"u1"}'

The response already came back empty in our builds, so callers see no change. The scan now starts at the lower bound's position when the range is inverted, so the page is empty by construction, as it already was forward and on the primary index.

get_kv_rows_inverted_range_test checks an inverted range on both indexes in both directions. The contract is deployed to 1secrev so that its secondary partition comes first in the index, and the reverse scan lands on the index's first entry. The test also passes against the old code, because the stray read happened to come back empty. With a temporary assertion on the decrement, the test tripped it on the old code, and the assertion stayed silent with the fix.

The reverse secondary-index scan starts at the upper bound and walks down to begin, the lower bound's position. With upper_bound below lower_bound it started below begin, so its first step down decremented the index's begin() whenever the table's partition is the first in the whole secondary index: undefined behavior, reachable by any API caller against the contract whose account sorts first. Start at begin instead, so an inverted range is empty, as it already is forward and on the primary index.
@heifner
heifner requested review from a team and huangminghuang September 25, 2026 17:35

@huangminghuang huangminghuang 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.

Reviewed the diff and surrounding index and bounds-handling code at f7b5123. No actionable findings. Validation was source-based; I did not run the PR tests locally.

@heifner
heifner merged commit 996be2d into master Sep 25, 2026
13 checks passed
@heifner
heifner deleted the fix/secondary-reverse-inverted-range branch September 25, 2026 20:29
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.

2 participants