Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
10 changes: 9 additions & 1 deletion src/Query/OrderedQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
12 changes: 12 additions & 0 deletions tests/Data/Entries/EntryQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
Loading