[PATCH] gdi32: Fix out-of-bounds reads in bitmapinfo_from_user_bitmapinfo (Valgrind)
Alex Henrie
alexhenrie24 at gmail.com
Sun Oct 13 22:44:54 CDT 2019
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 <alexhenrie24 at gmail.com>
---
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
More information about the wine-devel
mailing list