Alexandre Julliard : gdi32: Fix handling of invalid pen styles.

Alexandre Julliard julliard at winehq.org
Wed Dec 28 13:44:33 CST 2011


Module: wine
Branch: master
Commit: bbd7f4e0e399f6b207e2e25e5e8c076724926a25
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bbd7f4e0e399f6b207e2e25e5e8c076724926a25

Author: Alexandre Julliard <julliard at 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);




More information about the wine-cvs mailing list