Skip to content

Commit c1f7b87

Browse files
authored
Fix MSVC C4267 warnings in gd.c (GH-17680)
These warnings are about conversion from `size_t` to a smaller type[1], and in this case because `gdIOCtx` works with `int` lengths. Two of these warnings are harmless, and we resolve them by using `size_t` in the first place, and adding a cast (plus an assertion), respectively. The others actually hint at potential issues when reading image data with more than `INT_MAX` bytes; we catch that upfront, and throw a `ValueError` and a warning, respectively. [1] <https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4267>
1 parent 4373c60 commit c1f7b87

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

ext/gd/gd.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,8 @@ gdImagePtr _php_image_create_from_string(zend_string *data, const char *tn, gdIm
14091409
gdImagePtr im;
14101410
gdIOCtx *io_ctx;
14111411

1412-
io_ctx = gdNewDynamicCtxEx(ZSTR_LEN(data), ZSTR_VAL(data), 0);
1412+
ZEND_ASSERT(ZSTR_LEN(data) <= INT_MAX); /* checked in imagecreatefromstring() */
1413+
io_ctx = gdNewDynamicCtxEx((int) ZSTR_LEN(data), ZSTR_VAL(data), 0);
14131414

14141415
if (!io_ctx) {
14151416
return NULL;
@@ -1439,6 +1440,10 @@ PHP_FUNCTION(imagecreatefromstring)
14391440
Z_PARAM_STR(data)
14401441
ZEND_PARSE_PARAMETERS_END();
14411442

1443+
if (ZSTR_LEN(data) > INT_MAX) {
1444+
zend_argument_value_error(1, "is too long");
1445+
}
1446+
14421447
imtype = _php_image_type(data);
14431448

14441449
switch (imtype) {
@@ -1562,17 +1567,23 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
15621567
buff = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
15631568

15641569
if (!buff) {
1565-
php_error_docref(NULL, E_WARNING,"Cannot read image data");
1570+
php_error_docref(NULL, E_WARNING, "Cannot read image data");
1571+
goto out_err;
1572+
}
1573+
1574+
if (ZSTR_LEN(buff) > INT_MAX) {
1575+
zend_string_release_ex(buff, 0);
1576+
php_error_docref(NULL, E_WARNING, "Cannot read images with more than %d bytes", INT_MAX);
15661577
goto out_err;
15671578
}
15681579

15691580
/* needs to be malloc (persistent) - GD will free() it later */
15701581
pstr = pestrndup(ZSTR_VAL(buff), ZSTR_LEN(buff), 1);
1571-
io_ctx = gdNewDynamicCtxEx(ZSTR_LEN(buff), pstr, 0);
1582+
io_ctx = gdNewDynamicCtxEx((int) ZSTR_LEN(buff), pstr, 0);
15721583
if (!io_ctx) {
15731584
pefree(pstr, 1);
15741585
zend_string_release_ex(buff, 0);
1575-
php_error_docref(NULL, E_WARNING,"Cannot allocate GD IO context");
1586+
php_error_docref(NULL, E_WARNING, "Cannot allocate GD IO context");
15761587
goto out_err;
15771588
}
15781589

@@ -1796,7 +1807,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, cons
17961807
fflush(fp);
17971808
fclose(fp);
17981809
} else {
1799-
int b;
1810+
size_t b;
18001811
FILE *tmp;
18011812
char buf[4096];
18021813
zend_string *path;
@@ -2983,7 +2994,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode)
29832994
zend_long X, Y, COL;
29842995
zend_string *C;
29852996
gdImagePtr im;
2986-
int ch = 0, col, x, y, i, l = 0;
2997+
int ch = 0, col, x, y, i;
2998+
size_t l = 0;
29872999
unsigned char *str = NULL;
29883000
zend_object *font_obj = NULL;
29893001
zend_long font_int = 0;
@@ -4337,7 +4349,9 @@ static void _php_image_output_putc(struct gdIOCtx *ctx, int c) /* {{{ */
43374349

43384350
static int _php_image_output_putbuf(struct gdIOCtx *ctx, const void* buf, int l) /* {{{ */
43394351
{
4340-
return php_write((void *)buf, l);
4352+
size_t written = php_write((void *)buf, l);
4353+
ZEND_ASSERT(written <= INT_MAX); /* since l <= INT_MAX */
4354+
return (int) written;
43414355
} /* }}} */
43424356

43434357
static void _php_image_output_ctxfree(struct gdIOCtx *ctx) /* {{{ */

0 commit comments

Comments
 (0)