Skip to content

Commit

Permalink
fix: Avoid integer overflows in function png_xy_from_XYZ
Browse files Browse the repository at this point in the history
Reviewed-by: Cosmin Truta <ctruta@gmail.com>
Signed-off-by: John Bowler <jbowler@acm.org>
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
  • Loading branch information
jbowler authored and ctruta committed Oct 13, 2024
1 parent c317fe3 commit f45531c
Showing 1 changed file with 24 additions and 16 deletions.
40 changes: 24 additions & 16 deletions png.c
Original file line number Diff line number Diff line change
Expand Up @@ -1249,52 +1249,60 @@ png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1,
static int
png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
{
png_int_32 d, dred, dgreen, dwhite, whiteX, whiteY;
png_int_32 d, dred, dgreen, dblue, dwhite, whiteX, whiteY;

/* 'd' in each of the blocks below is just X+Y+Z for each component,
* x, y and z are X,Y,Z/(X+Y+Z).
*/
d = XYZ->red_X;
if (png_safe_add(&d, XYZ->red_Y, XYZ->red_Z))
return 1;
if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
dred = d;
if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, dred) == 0)
return 1;
if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, dred) == 0)
return 1;
dred = d;
whiteX = XYZ->red_X;
whiteY = XYZ->red_Y;

d = XYZ->green_X;
if (png_safe_add(&d, XYZ->green_Y, XYZ->green_Z))
return 1;
if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
dgreen = d;
if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, dgreen) == 0)
return 1;
if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, dgreen) == 0)
return 1;
dgreen = d;
whiteX += XYZ->green_X;
whiteY += XYZ->green_Y;

d = XYZ->blue_X;
if (png_safe_add(&d, XYZ->blue_Y, XYZ->blue_Z))
return 1;
if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
dblue = d;
if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, dblue) == 0)
return 1;
if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, dblue) == 0)
return 1;
whiteX += XYZ->blue_X;
whiteY += XYZ->blue_Y;

/* The reference white is simply the sum of the end-point (X,Y,Z) vectors so
* the fillowing calculates (X+Y+Z) of the reference white (media white,
* encoding white) itself:
*/
d = dblue;
if (png_safe_add(&d, dred, dgreen))
return 1;

dwhite = d;

/* Find the white X,Y values from the sum of the red, green and blue X,Y
* values.
*/
d = XYZ->red_X;
if (png_safe_add(&d, XYZ->green_X, XYZ->blue_X))
return 1;
whiteX = d;

d = XYZ->red_Y;
if (png_safe_add(&d, XYZ->green_Y, XYZ->blue_Y))
return 1;
whiteY = d;

if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
return 1;
if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
Expand Down

0 comments on commit f45531c

Please sign in to comment.