diff --git a/system/Images/Handlers/BaseHandler.php b/system/Images/Handlers/BaseHandler.php index 9301b1573c23..d3aff71f4d10 100644 --- a/system/Images/Handlers/BaseHandler.php +++ b/system/Images/Handlers/BaseHandler.php @@ -720,29 +720,29 @@ public function __call(string $name, array $args = []) */ protected function reproportion() { - if (($this->width === 0 && $this->height === 0) || $this->image()->origWidth === 0 || $this->image()->origHeight === 0 || (! ctype_digit((string) $this->width) && ! ctype_digit((string) $this->height)) || ! ctype_digit((string) $this->image()->origWidth) || ! ctype_digit((string) $this->image()->origHeight)) { + $image = $this->image(); + $origW = (int) $image->origWidth; + $origH = (int) $image->origHeight; + $w = (int) $this->width; + $h = (int) $this->height; + + if (! is_numeric($this->width) || ! is_numeric($this->height) || $origW === 0 || $origH === 0 || ($w === 0 && $h === 0)) { return; } - // Sanitize - $this->width = (int) $this->width; - $this->height = (int) $this->height; + $this->width = $w; + $this->height = $h; if ($this->masterDim !== 'width' && $this->masterDim !== 'height') { - if ($this->width > 0 && $this->height > 0) { - $this->masterDim = ((($this->image()->origHeight / $this->image()->origWidth) - ($this->height / $this->width)) < 0) ? 'width' : 'height'; - } else { - $this->masterDim = ($this->height === 0) ? 'width' : 'height'; - } - } elseif (($this->masterDim === 'width' && $this->width === 0) || ($this->masterDim === 'height' && $this->height === 0) - ) { + $this->masterDim = ($h === 0 || ($w > 0 && (($origH / $origW) - ($h / $w) < 0))) ? 'width' : 'height'; + } elseif (($this->masterDim === 'width' && $w === 0) || ($this->masterDim === 'height' && $h === 0)) { return; } if ($this->masterDim === 'width') { - $this->height = (int) ceil($this->width * $this->image()->origHeight / $this->image()->origWidth); + $this->height = (int) ceil($w * $origH / $origW); } else { - $this->width = (int) ceil($this->image()->origWidth * $this->height / $this->image()->origHeight); + $this->width = (int) ceil($origW * $h / $origH); } } diff --git a/tests/system/Images/BaseHandlerTest.php b/tests/system/Images/BaseHandlerTest.php index 17bc3c00eb70..05e6d227985b 100644 --- a/tests/system/Images/BaseHandlerTest.php +++ b/tests/system/Images/BaseHandlerTest.php @@ -20,6 +20,7 @@ use CodeIgniter\Test\CIUnitTestCase; use org\bovigo\vfs\vfsStream; use PHPUnit\Framework\Attributes\Group; +use ReflectionMethod; /** * Test the common image processing functionality. @@ -130,4 +131,25 @@ public function testImageHandled(): void $handler->withFile($this->path); $this->assertSame($this->path, $handler->getPathname()); } + + public function testReproportionWithFloatZero(): void + { + $handler = Services::image('gd', null, false); + $handler->withFile($this->path); + + $image = $handler->getFile(); + $image->origWidth = 0.0; + $image->origHeight = 0.0; + + // Use reflection to test the protected method reproportion directly + // This should not throw a DivisionByZeroError + $expectedWidth = $handler->getWidth(); + $expectedHeight = $handler->getHeight(); + + $method = new ReflectionMethod($handler::class, 'reproportion'); + $method->invoke($handler); + + $this->assertSame($expectedWidth, $handler->getWidth()); + $this->assertSame($expectedHeight, $handler->getHeight()); + } }