Skip to content

Commit dddbca6

Browse files
lacatoiredevnexen
authored andcommitted
ext/gd: report $size with the argument number of the function called
php_imagettftext_common() serves the bbox functions, where $size is argument #1, and the drawing ones, where it is #2, but its two size checks hardcode 2. imageftbbox(NAN, ...) therefore blamed $angle. Also fix the upper bound itself: (double)LONG_MAX rounds up to 2^63, so (double)LONG_MAX / 64 is 2^57 and the check let 2^57 through, whose product with 64 is LONG_MAX + 1. The bound is now exclusive, and the reported values use integer division, which gives the largest size that is actually representable. The lower bound stays inclusive: (double)LONG_MIN / 64 is exactly -2^57 and its product with 64 is LONG_MIN. Co-authored-by: NickSdot <32384907+NickSdot@users.noreply.github.com> Close GH-23541
1 parent 0bf872b commit dddbca6

3 files changed

Lines changed: 74 additions & 3 deletions

File tree

ext/gd/gd.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,14 +3422,16 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode)
34223422
im = php_gd_libgdimageptr_from_zval_p(IM);
34233423
}
34243424

3425+
uint32_t ptsize_arg_num = mode == TTFTEXT_BBOX ? 1 : 2;
3426+
34253427
// FT_F26Dot6 is a signed long alias
3426-
if (ptsize < (double)LONG_MIN / 64 || ptsize > (double)LONG_MAX / 64) {
3427-
zend_argument_value_error(2, "must be between " ZEND_LONG_FMT " and " ZEND_LONG_FMT, (zend_long)((double)LONG_MIN / 64), (zend_long)((double)LONG_MAX / 64));
3428+
if (ptsize < (double)LONG_MIN / 64 || ptsize >= (double)LONG_MAX / 64) {
3429+
zend_argument_value_error(ptsize_arg_num, "must be between " ZEND_LONG_FMT " and " ZEND_LONG_FMT, (zend_long)(LONG_MIN / 64), (zend_long)(LONG_MAX / 64));
34283430
RETURN_THROWS();
34293431
}
34303432

34313433
if (UNEXPECTED(!zend_finite(ptsize))) {
3432-
zend_argument_value_error(2, "must be finite");
3434+
zend_argument_value_error(ptsize_arg_num, "must be finite");
34333435
RETURN_THROWS();
34343436
}
34353437

ext/gd/tests/gh18243.phpt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,16 @@ try {
3434
} catch (\ValueError $e) {
3535
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
3636
}
37+
38+
try {
39+
imagettftext($im, 144115188075855872.0, 0, 15, 60, 0, $font, "");
40+
} catch (Throwable $e) {
41+
echo $e::class, ': ', $e->getMessage(), "\n";
42+
}
3743
?>
3844
--EXPECTF--
3945
ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
4046
ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
4147
ValueError: imagettftext(): Argument #2 ($size) must be finite
4248
ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
49+
ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
--TEST--
2+
The $size errors name the argument of the function that was called
3+
--EXTENSIONS--
4+
gd
5+
--SKIPIF--
6+
<?php
7+
if (!function_exists('imageftbbox')) die('skip imageftbbox() not available');
8+
?>
9+
--FILE--
10+
<?php
11+
$font = __DIR__ . '/Rochester-Regular.otf';
12+
$image = imagecreatetruecolor(100, 80);
13+
14+
/* $size is argument #1 here */
15+
foreach ([NAN, INF, PHP_INT_MAX, PHP_INT_MIN] as $size) {
16+
try {
17+
imageftbbox($size, 0.0, $font, 'A');
18+
} catch (Throwable $e) {
19+
echo $e::class, ': ', $e->getMessage(), "\n";
20+
}
21+
try {
22+
imagettfbbox($size, 0.0, $font, 'A');
23+
} catch (Throwable $e) {
24+
echo $e::class, ': ', $e->getMessage(), "\n";
25+
}
26+
}
27+
28+
/* and argument #2 here */
29+
foreach ([NAN, INF] as $size) {
30+
try {
31+
imagefttext($image, $size, 0.0, 15, 60, 0, $font, 'A');
32+
} catch (Throwable $e) {
33+
echo $e::class, ': ', $e->getMessage(), "\n";
34+
}
35+
try {
36+
imagettftext($image, $size, 0.0, 15, 60, 0, $font, 'A');
37+
} catch (Throwable $e) {
38+
echo $e::class, ': ', $e->getMessage(), "\n";
39+
}
40+
}
41+
42+
/* the type error already agreed with the signature and still does */
43+
try {
44+
imageftbbox('x', 0.0, $font, 'A');
45+
} catch (Throwable $e) {
46+
echo $e::class, ': ', $e->getMessage(), "\n";
47+
}
48+
?>
49+
--EXPECTF--
50+
ValueError: imageftbbox(): Argument #1 ($size) must be finite
51+
ValueError: imagettfbbox(): Argument #1 ($size) must be finite
52+
ValueError: imageftbbox(): Argument #1 ($size) must be between %i and %d
53+
ValueError: imagettfbbox(): Argument #1 ($size) must be between %i and %d
54+
ValueError: imageftbbox(): Argument #1 ($size) must be between %i and %d
55+
ValueError: imagettfbbox(): Argument #1 ($size) must be between %i and %d
56+
ValueError: imageftbbox(): Argument #1 ($size) must be between %i and %d
57+
ValueError: imagettfbbox(): Argument #1 ($size) must be between %i and %d
58+
ValueError: imagefttext(): Argument #2 ($size) must be finite
59+
ValueError: imagettftext(): Argument #2 ($size) must be finite
60+
ValueError: imagefttext(): Argument #2 ($size) must be between %i and %d
61+
ValueError: imagettftext(): Argument #2 ($size) must be between %i and %d
62+
TypeError: imageftbbox(): Argument #1 ($size) must be of type float, string given

0 commit comments

Comments
 (0)