Skip to content

Refuse a page size that is not a page - #159

Merged
jagerman merged 1 commit into
session-foundation:clientfrom
Bilb:require-page
Sep 14, 2026
Merged

jagerman merged 1 commit into
session-foundation:clientfrom
Bilb:require-page

Conversation

@Bilb

@Bilb Bilb commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Conversation::messages passes limit straight through to SQLite as LIMIT ?, where a negative value means no limit at all and zero means the end of the history. A caller asking for -1 messages gets every message in the conversation loaded into memory; one asking for 0 gets an empty page that reads as the end of the history rather than an error.

The parameter was undocumented, so neither reading was wrong from the caller's side — the header explains before and include_deleted at length and said nothing about the range of limit.

What this does

_require_page joins the other _require_* guards on the calling thread, where a caller bug surfaces at the call site with a stack still under it, rather than as a string in an error leg.

The two terminal overloads are the only callers of _messages, so guarding them covers all eight public spellings. The defaulted overloads pass 50 and are unaffected.

The header now states the contract, including that there is deliberately no "no limit" spelling: a conversation's history has no upper bound, so a caller that wants all of it pages.

Testing

New case Client: a page size has to be a page covers 0, -1 and -50 across both the waiting and handler forms, with a positive control. [client] is green: 1006 assertions in 134 test cases.

Note for consumers

This turns a silent unbounded load into a refusal, so anything currently passing a non-positive limit and relying on getting everything back will start throwing. Nothing in-tree did.

Conversation::messages passes `limit` straight through to SQLite as `LIMIT ?`,
where a negative value means no limit at all and zero means the end of the
history. So a caller asking for -1 messages gets every message in the
conversation loaded into memory, and one asking for 0 gets an empty page that
looks like the end of the history rather than an error.

The parameter was undocumented, so neither reading was wrong from the caller's
side: the header explains `before` and `include_deleted` at length and said
nothing about the range of `limit`.

_require_page joins the other _require_ guards on the calling thread, where a
caller bug surfaces at the call site with a stack still under it rather than as
a string in an error leg. The two terminal overloads are the only callers of
_messages, so guarding them covers all eight public spellings; the defaulted
ones pass 50 and are unaffected.
@jagerman
jagerman merged commit d4ff59c into session-foundation:client Sep 14, 2026
1 check failed
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