Skip to content

fix(search): compute the profile size gates in long, not int - #985

Open
m4bard wants to merge 1 commit into
Listenarrs:canaryfrom
m4bard:fix/profile-size-int-overflow
Open

m4bard wants to merge 1 commit into
Listenarrs:canaryfrom
m4bard:fix/profile-size-int-overflow

Conversation

@m4bard

@m4bard m4bard commented Sep 14, 2026

Copy link
Copy Markdown

Fixes #977.

SearchResultScorer's size gate multiplies QualityProfile.MinimumSize and MaximumSize, both int megabytes, by 1024 * 1024 before comparing against a result's long byte size. At 2048 MB the multiply overflows int and wraps to -2147483648, so the two gates fail in opposite directions: Maximum rejects every size, since everything is greater than a negative number, and Minimum stops rejecting anything, since nothing is smaller than one. The indexer size gate a few lines above already casts to long first, which is what makes the two profile lines next to it look like an oversight rather than a design choice.

The fix is the same cast the indexer gate already uses, applied to both lines.

Two theories, each with a control row below the overflow threshold so a change that simply stopped rejecting, or simply started rejecting, would fail the control. Without the casts, the four overflow rows fail and the two controls pass.

Suite run against current canary (upstream/canary at a630572e9, which this branch is built on): targeted filter QualityProfileScoringTests, 23 passed, 0 failed.

Found while wiring Indexer.MaximumSize in #921 and kept out of that PR as a separate bug. Full mechanism and the repro test are in the issue.

Disclosure: drafted with Claude Code at my direction; I read the cited code at commit a630572 and reviewed this before posting.

QualityProfile.MinimumSize and MaximumSize are int megabytes, and the scorer
multiplied them by 1024 * 1024 in int arithmetic. 2048 MB is one byte past
int.MaxValue once multiplied, so a profile capped at 2 GB or more wraps
negative and the two gates fail in opposite directions: every release is
"larger than" a negative maximum and is rejected as too large, and nothing is
"smaller than" a negative minimum so the minimum silently stops applying. The
quality profile form puts no upper bound on either input, and a 2 GB ceiling on
an audiobook profile is an ordinary thing to set.

The fix is the cast the indexer size gate one block above already uses.

Both theories carry a control row below the overflow, so a fix that simply
stopped rejecting, or simply started rejecting, fails them. Without the casts
the four overflow rows fail and the two control rows pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@m4bard
m4bard requested a review from a team September 14, 2026 09:20
@m4bard
m4bard force-pushed the fix/profile-size-int-overflow branch from 3701a1e to 5d3937f Compare September 15, 2026 18:35
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.

A quality profile size limit of 2 GB or more rejects every release

1 participant