Module: wine Branch: master Commit: bbd7f4e0e399f6b207e2e25e5e8c076724926a25 URL: http://source.winehq.org/git/wine.git/?a=commit;h=bbd7f4e0e399f6b207e2e25e5e...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Dec 28 13:52:51 2011 +0100
gdi32: Fix handling of invalid pen styles.
---
dlls/gdi32/pen.c | 87 +++++++++++++++++++++++++++++++----------------- dlls/gdi32/tests/pen.c | 20 ++++++++++- 2 files changed, 75 insertions(+), 32 deletions(-)
diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c index 1f92b87..2f69375 100644 --- a/dlls/gdi32/pen.c +++ b/dlls/gdi32/pen.c @@ -89,25 +89,32 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
if (!(penPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*penPtr) ))) return 0;
- if (pen->lopnStyle == PS_USERSTYLE || pen->lopnStyle == PS_ALTERNATE) - penPtr->logpen.elpPenStyle = PS_SOLID; - else - penPtr->logpen.elpPenStyle = pen->lopnStyle; - if (pen->lopnStyle == PS_NULL) - { - penPtr->logpen.elpWidth = 1; - penPtr->logpen.elpColor = RGB(0, 0, 0); - } - else - { - penPtr->logpen.elpWidth = abs(pen->lopnWidth.x); - penPtr->logpen.elpColor = pen->lopnColor; - } + penPtr->logpen.elpPenStyle = pen->lopnStyle; + penPtr->logpen.elpWidth = abs(pen->lopnWidth.x); + penPtr->logpen.elpColor = pen->lopnColor; penPtr->logpen.elpBrushStyle = BS_SOLID; penPtr->logpen.elpHatch = 0; penPtr->logpen.elpNumEntries = 0; penPtr->logpen.elpStyleEntry[0] = 0;
+ switch (pen->lopnStyle) + { + case PS_SOLID: + case PS_DASH: + case PS_DOT: + case PS_DASHDOT: + case PS_DASHDOTDOT: + case PS_INSIDEFRAME: + break; + case PS_NULL: + penPtr->logpen.elpWidth = 1; + penPtr->logpen.elpColor = 0; + break; + default: + penPtr->logpen.elpPenStyle = PS_SOLID; + break; + } + if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_PEN, &pen_funcs ))) HeapFree( GetProcessHeap(), 0, penPtr ); return hpen; @@ -124,10 +131,26 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, PENOBJ * penPtr; HPEN hpen;
- if ((style & PS_STYLE_MASK) == PS_USERSTYLE) + if ((style_count || style_bits) && (style & PS_STYLE_MASK) != PS_USERSTYLE) { - if(((INT)style_count) <= 0) - return 0; + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + switch (style & PS_STYLE_MASK) + { + case PS_NULL: + return CreatePen( PS_NULL, 0, brush->lbColor ); + + case PS_SOLID: + case PS_DASH: + case PS_DOT: + case PS_DASHDOT: + case PS_DASHDOTDOT: + break; + + case PS_USERSTYLE: + if (((INT)style_count) <= 0) return 0;
if ((style_count > 16) || !style_bits) { @@ -152,28 +175,31 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, return 0; } } - } - else - { - if (style_count || style_bits) + break; + + case PS_INSIDEFRAME: /* applicable only for geometric pens */ + if ((style & PS_TYPE_MASK) != PS_GEOMETRIC) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } - } - - if ((style & PS_STYLE_MASK) == PS_NULL) - return CreatePen( PS_NULL, 0, brush->lbColor ); + break;
- if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) - { - /* PS_ALTERNATE is applicable only for cosmetic pens */ - if ((style & PS_STYLE_MASK) == PS_ALTERNATE) + case PS_ALTERNATE: /* applicable only for cosmetic pens */ + if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } + break;
+ default: + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) + { if (brush->lbHatch && ((brush->lbStyle != BS_SOLID) && (brush->lbStyle != BS_HOLLOW))) { static int fixme_hatches_shown; @@ -182,8 +208,7 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, } else { - /* PS_INSIDEFRAME is applicable only for geometric pens */ - if ((style & PS_STYLE_MASK) == PS_INSIDEFRAME || width != 1) + if (width != 1) { SetLastError(ERROR_INVALID_PARAMETER); return 0; diff --git a/dlls/gdi32/tests/pen.c b/dlls/gdi32/tests/pen.c index fa2fa88..3a198a1 100644 --- a/dlls/gdi32/tests/pen.c +++ b/dlls/gdi32/tests/pen.c @@ -53,7 +53,13 @@ static void test_logpen(void) { PS_NULL, 123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 }, { PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56), PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56) }, { PS_USERSTYLE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, - { PS_ALTERNATE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) } + { PS_ALTERNATE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, + { 9, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, + { 10, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, + { 11, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, + { 13, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, + { 14, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, + { 15, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }, }; INT i, size; HPEN hpen; @@ -216,6 +222,12 @@ static void test_logpen(void) ok(hpen == 0, "ExtCreatePen should fail\n"); goto test_geometric_pens; } + if (pen[i].style > PS_ALTERNATE) + { + ok(hpen == 0, "ExtCreatePen should fail\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong last error value %d\n", GetLastError()); + goto test_geometric_pens; + } ok(hpen != 0, "ExtCreatePen error %d\n", GetLastError());
obj_type = GetObjectType(hpen); @@ -335,6 +347,12 @@ test_geometric_pens: ok(hpen == 0, "ExtCreatePen should fail\n"); continue; } + if (pen[i].style > PS_ALTERNATE) + { + ok(hpen == 0, "ExtCreatePen should fail\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong last error value %d\n", GetLastError()); + continue; + } ok(hpen != 0, "ExtCreatePen error %d\n", GetLastError());
obj_type = GetObjectType(hpen);