main
tag: launch-2026-06-01
tag: magicmirror-v0.1.1
tag: magicmirror-v0.3.0
tag: mnw-cli-v0.1.2
tag: mnw-cli-v0.1.3
tag: mnw-cli-v0.1.4
tag: pom-v0.4.1
tag: pom-v0.4.2
tag: pom-v0.4.3
tag: pom-v0.4.4
tag: pom-v0.4.5
tag: wam-v0.3.0
tag: wam-v0.3.1
Files
Commits
Tags
Notes
Issues
ux: clamp library feed pagination like sibling paginators
library_tab_feed used unwrap_or(1).max(1) with no upper bound, while
feed/discover/admin/issues all clamp(1, 1_000_000_000). A large ?page=
issued an unbounded SQL OFFSET deep-scan. Clamp it to match, and add a
regression test.
ultra-fuzz Run 5 M-UX1.
Co-Authored-By
Claude Opus 4.8 <noreply@anthropic.com>
2 files changed,
+24 insertions,
-2 deletions
194
194
);
195
195
}
196
196
197
+
#[tokio::test]
198
+
async fn library_feed_huge_page_is_clamped_not_overflowing() {
199
+
// M-UX1: the feed tab's `?page=` must be clamped like every sibling
200
+
// paginator. A large in-range value (above the 1e9 clamp ceiling) should
201
+
// return a valid empty page, with the OFFSET bounded by the clamp rather
202
+
// than running a multi-billion-row deep-scan.
203
+
let mut h = TestHarness::new().await;
204
+
h.signup("feedpage", "feedpage@test.com", "password123").await;
205
+
206
+
let resp = h
207
+
.client
208
+
.get("/library/tabs/feed?page=4000000000")
209
+
.await;
210
+
assert_eq!(
211
+
resp.status, 200,
212
+
"large page should clamp to a valid empty page, got {} {}",
213
+
resp.status, resp.text
214
+
);
215
+
}
216
+
197
217
#[tokio::test]
198
218
async fn follow_nonexistent_rejected() {
199
219
let mut h = TestHarness::new().await;
225
225
) -> Result<impl IntoResponse> {
226
226
use crate::templates::LibraryFeedTabTemplate;
227
227
228
-
let page = query.page.unwrap_or(1).max(1);
229
-
// Widen to i64 BEFORE multiplying to avoid u32 overflow on a large `?page=`.
228
+
// Clamp the upper bound like every sibling paginator (feed/discover/
229
+
// admin/issues): an unbounded `?page=` would issue a giant SQL OFFSET
230
+
// deep-scan. Widen to i64 BEFORE multiplying to avoid u32 overflow.
231
+
let page = query.page.unwrap_or(1).clamp(1, 1_000_000_000);
230
232
let offset = (page as i64 - 1) * constants::FEED_PAGE_SIZE as i64;
231
233
232
234
let total_items = db::follows::count_followed_feed_items(&state.db, user.id).await? as u32;