diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 6d84d98abd..41794417e7 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -72,7 +72,16 @@ public function limit($value) public function offset($value) { - $this->offset = max(0, $value); + $value = max(0, $value); + + // A large page number can overflow the offset arithmetic in forPage()/chunk() into a + // float, which array_slice() rejects. Clamp an out-of-range offset to PHP_INT_MAX so it + // yields an empty page instead of throwing. + if (is_float($value)) { + $value = $value >= PHP_INT_MAX ? PHP_INT_MAX : (int) $value; + } + + $this->offset = $value; return $this; } diff --git a/src/Query/OrderedQueryBuilder.php b/src/Query/OrderedQueryBuilder.php index 0beb43d667..10d622114a 100644 --- a/src/Query/OrderedQueryBuilder.php +++ b/src/Query/OrderedQueryBuilder.php @@ -87,7 +87,15 @@ public function limit($value) public function offset($value) { - $this->offset = max(0, $value); + $value = max(0, $value); + + // Mirrors the overflow guard in Query\Builder::offset() - an out-of-range offset + // shouldn't reach Collection::skip() as a float. + if (is_float($value)) { + $value = $value >= PHP_INT_MAX ? PHP_INT_MAX : (int) $value; + } + + $this->offset = $value; return $this; } diff --git a/tests/Data/Entries/EntryQueryBuilderTest.php b/tests/Data/Entries/EntryQueryBuilderTest.php index 014f68545c..35e34b3a91 100644 --- a/tests/Data/Entries/EntryQueryBuilderTest.php +++ b/tests/Data/Entries/EntryQueryBuilderTest.php @@ -859,6 +859,18 @@ public function entries_are_found_using_offset() $this->assertEquals(['Post 2', 'Post 3'], $entries->map->title->all()); } + #[Test] + public function it_returns_an_empty_page_when_the_offset_overflows() + { + $this->createDummyCollectionAndEntries(); + + // A page number large enough to overflow the offset arithmetic used to crash + // array_slice() with a float; it should just yield an empty page. + $entries = Entry::query()->forPage(PHP_INT_MAX, 6)->get(); + + $this->assertCount(0, $entries); + } + #[Test] public function entries_are_found_using_where_has_when_max_items_1() {