gdi32: Sanitize the DIB information for DIB pattern brushes.

This commit is contained in:
Alexandre Julliard 2011-11-02 12:22:44 +01:00
parent 6bf6575c5c
commit 7f7dd82c7b
4 changed files with 31 additions and 18 deletions

View File

@ -53,21 +53,6 @@ static const struct gdi_obj_funcs brush_funcs =
BRUSH_DeleteObject /* pDeleteObject */
};
static void *dib_copy(const BITMAPINFO *info, UINT coloruse)
{
BITMAPINFO *newInfo;
INT size;
if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS)
size = info->bmiHeader.biSizeImage;
else
size = get_dib_image_size(info);
size += bitmap_info_size( info, coloruse );
if ((newInfo = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( newInfo, info, size );
return newInfo;
}
/***********************************************************************
* CreateBrushIndirect (GDI32.@)
@ -117,8 +102,8 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
case BS_DIBPATTERNPT:
ptr->logbrush.lbStyle = BS_DIBPATTERN;
ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
ptr->logbrush.lbColor);
ptr->logbrush.lbHatch = (ULONG_PTR)copy_packed_dib( (BITMAPINFO *) ptr->logbrush.lbHatch,
ptr->logbrush.lbColor );
if (!ptr->logbrush.lbHatch) goto error;
break;
@ -129,7 +114,7 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
ptr->logbrush.lbStyle = BS_DIBPATTERN;
if (!(bmi = GlobalLock( h ))) goto error;
ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( bmi, ptr->logbrush.lbColor);
ptr->logbrush.lbHatch = (ULONG_PTR)copy_packed_dib( bmi, ptr->logbrush.lbColor );
GlobalUnlock( h );
if (!ptr->logbrush.lbHatch) goto error;
break;

View File

@ -1113,6 +1113,23 @@ void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info )
if (info->bmiHeader.biBitCount <= 8) fill_default_color_table( info );
}
BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage )
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *ret, *info = (BITMAPINFO *)buffer;
int info_size, image_size;
if (!bitmapinfo_from_user_bitmapinfo( info, src_info, usage, FALSE )) return NULL;
info_size = bitmap_info_size( info, usage );
image_size = get_dib_image_size( info );
if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + image_size )))
{
memcpy( ret, info, info_size );
memcpy( (char *)ret + info_size, (char *)src_info + bitmap_info_size(src_info,usage), image_size );
}
return ret;
}
/******************************************************************************
* GetDIBits [GDI32.@]

View File

@ -230,6 +230,7 @@ extern DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src
/* bitmap.c */
extern void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) DECLSPEC_HIDDEN;
extern BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage ) DECLSPEC_HIDDEN;
extern BOOL get_bitmap_image( HBITMAP hbitmap, BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) DECLSPEC_HIDDEN;

View File

@ -192,6 +192,16 @@ static void test_pattern_brush(void)
ret = GlobalFlags( mem );
ok( ret == 2, "wrong flags %x\n", ret );
info->bmiHeader.biBitCount = 8;
info->bmiHeader.biCompression = BI_RLE8;
brush = CreateDIBPatternBrushPt( info, DIB_RGB_COLORS );
ok( !brush, "CreateDIBPatternBrushPt succeeded\n" );
info->bmiHeader.biBitCount = 4;
info->bmiHeader.biCompression = BI_RLE4;
brush = CreateDIBPatternBrushPt( info, DIB_RGB_COLORS );
ok( !brush, "CreateDIBPatternBrushPt succeeded\n" );
br.lbStyle = BS_DIBPATTERN8X8;
br.lbColor = DIB_RGB_COLORS;
br.lbHatch = (ULONG_PTR)mem;