summaryrefslogtreecommitdiff
path: root/src/gd_bmp.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2018-01-26 22:30:10 -0500
committerMike Frysinger <vapier@gentoo.org>2018-01-26 22:30:10 -0500
commit14ca9e4b235e131710bb0b84a26a25cb767af363 (patch)
treef368e9434457edf721bca0ba351631e924e4d683 /src/gd_bmp.c
parent5618b9e82ad392b22a31bf1741eb0ee017626b95 (diff)
downloadlibgd-14ca9e4b235e131710bb0b84a26a25cb767af363.tar.gz
bmp: check smallest negative value for undefined behavior
oss-fuzz pointed out: gd_bmp.c:641:18: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself This is a bit of a false positive issue as -2147483648 is -2147483648 with gcc/clang which we check for later on. But lets check for it up front to avoid the undefined behavior.
Diffstat (limited to 'src/gd_bmp.c')
-rw-r--r--src/gd_bmp.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/gd_bmp.c b/src/gd_bmp.c
index bbc2d26..ccafdcd 100644
--- a/src/gd_bmp.c
+++ b/src/gd_bmp.c
@@ -25,6 +25,7 @@
#endif
#include <stdio.h>
+#include <limits.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
@@ -636,6 +637,9 @@ static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info)
return 1;
}
+ /* Unlikely, but possible -- largest signed value won't fit in unsigned. */
+ if (info->height == 0 || info->height == INT_MIN)
+ return 1;
if (info->height < 0) {
info->topdown = 1;
info->height = -info->height;
@@ -645,8 +649,9 @@ static int bmp_read_windows_v3_info(gdIOCtxPtr infile, bmp_info_t *info)
info->type = BMP_PALETTE_4;
- if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 ||
- info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) {
+ /* Height was checked above. */
+ if (info->width <= 0 || info->numplanes <= 0 || info->depth <= 0 ||
+ info->numcolors < 0 || info->mincolors < 0) {
return 1;
}
@@ -706,6 +711,9 @@ static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info)
return 1;
}
+ /* Unlikely, but possible -- largest signed value won't fit in unsigned. */
+ if (info->height == 0 || info->height == INT_MIN)
+ return 1;
if (info->height < 0) {
info->topdown = 1;
info->height = -info->height;
@@ -715,12 +723,12 @@ static int bmp_read_os2_v2_info(gdIOCtxPtr infile, bmp_info_t *info)
info->type = BMP_PALETTE_4;
- if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 ||
- info->depth <= 0 || info->numcolors < 0 || info->mincolors < 0) {
+ /* Height was checked above. */
+ if (info->width <= 0 || info->numplanes <= 0 || info->depth <= 0 ||
+ info->numcolors < 0 || info->mincolors < 0) {
return 1;
}
-
return 0;
}