From: Alex Henrie Subject: [PATCH] gdi32: Fix out-of-bounds reads in bitmapinfo_from_user_bitmapinfo (Valgrind) Message-Id: <20191014034454.48511-2-alexhenrie24@gmail.com> Date: Sun, 13 Oct 2019 23:44:54 -0400 In-Reply-To: <20191014034454.48511-1-alexhenrie24@gmail.com> References: <20191014034454.48511-1-alexhenrie24@gmail.com> Do not attempt to copy the bitmap colormap if there is no bitmap colormap. Substitute the default colormap if possible. Signed-off-by: Alex Henrie --- dlls/gdi32/dib.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 3d267ba89c..7e9c21d3f5 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -204,14 +204,10 @@ static BOOL bitmapinfoheader_from_user_bitmapinfo( BITMAPINFOHEADER *dst, const static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info, UINT coloruse, BOOL allow_compression ) { - void *src_colors; - if (coloruse > DIB_PAL_COLORS + 1) return FALSE; /* FIXME: handle DIB_PAL_COLORS+1 format */ if (!bitmapinfoheader_from_user_bitmapinfo( &dst->bmiHeader, &info->bmiHeader )) return FALSE; if (!is_valid_dib_format( &dst->bmiHeader, allow_compression )) return FALSE; - src_colors = (char *)info + info->bmiHeader.biSize; - if (dst->bmiHeader.biCompression == BI_BITFIELDS) { /* bitfields are always at bmiColors even in larger structures */ @@ -220,31 +216,40 @@ static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO * } else if (dst->bmiHeader.biBitCount <= 8) { + const void *src_colors = (char *)info + info->bmiHeader.biSize; unsigned int colors = dst->bmiHeader.biClrUsed; unsigned int max_colors = 1 << dst->bmiHeader.biBitCount; - if (!colors) colors = max_colors; - else colors = min( colors, max_colors ); + colors = min( colors, max_colors ); if (coloruse == DIB_PAL_COLORS) { memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) ); max_colors = colors; } - else if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) - { - memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) ); - } else { - unsigned int i; - RGBTRIPLE *triple = (RGBTRIPLE *)src_colors; - for (i = 0; i < colors; i++) + if (!colors) { - dst->bmiColors[i].rgbRed = triple[i].rgbtRed; - dst->bmiColors[i].rgbGreen = triple[i].rgbtGreen; - dst->bmiColors[i].rgbBlue = triple[i].rgbtBlue; - dst->bmiColors[i].rgbReserved = 0; + src_colors = get_default_color_table( dst->bmiHeader.biBitCount ); + colors = max_colors; + } + + if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) + { + memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) ); + } + else + { + unsigned int i; + RGBTRIPLE *triple = (RGBTRIPLE *)src_colors; + for (i = 0; i < colors; i++) + { + dst->bmiColors[i].rgbRed = triple[i].rgbtRed; + dst->bmiColors[i].rgbGreen = triple[i].rgbtGreen; + dst->bmiColors[i].rgbBlue = triple[i].rgbtBlue; + dst->bmiColors[i].rgbReserved = 0; + } } } memset( dst->bmiColors + colors, 0, (max_colors - colors) * sizeof(RGBQUAD) ); -- 2.23.0