Skip to content

Commit

Permalink
Fix #2229 infinite loop in ceiling intervals in forHumans()
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed Oct 22, 2020
1 parent 6571aec commit 61b2c44
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/Carbon/CarbonInterval.php
Original file line number Diff line number Diff line change
Expand Up @@ -1541,13 +1541,19 @@ public function forHumans($syntax = null, $short = false, $parts = -1, $options

$intervalValues = $this;
$method = static::getRoundingMethodFromOptions($options);
$previousCount = INF;

if ($method) {
while (
\count($intervalValues->getNonZeroValues()) > $parts &&
($count = \count($keys = array_keys($intervalValues->getValuesSequence()))) > 1
) {
$intervalValues = $this->copy()->roundUnit($keys[$count - 2], 1, $method);
$intervalValues = $this->copy()->roundUnit(
$keys[min($count, $previousCount - 1) - 2],
1,
$method
);
$previousCount = $count;
}
}

Expand Down
13 changes: 13 additions & 0 deletions tests/CarbonInterval/ForHumansTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
namespace Tests\CarbonInterval;

use Carbon\Carbon;
use Carbon\CarbonInterface;
use Carbon\CarbonInterval;
use Symfony\Component\Translation\Loader\ArrayLoader;
Expand Down Expand Up @@ -362,6 +363,18 @@ public function testRoundCarryOverDoesntMatter()

$interval = CarbonInterval::days(2)->minutes(59)->seconds(62);
$this->assertEquals('2 days 59 minutes', $interval->forHumans(['parts' => 2]));

$start = Carbon::create(2009, 9)->startOfMonth();
$end = Carbon::create(2012, 2)->endOfMonth();

$interval = CarbonInterval::instance($start->diff($end))->forHumans(
Carbon::DIFF_ABSOLUTE,
false,
2,
Carbon::CEIL
);

$this->assertEquals('2 years 6 months', $interval);
}

public function testGetValuesSequence()
Expand Down

0 comments on commit 61b2c44

Please sign in to comment.