Alexandre Julliard : gdi32: Limit line drawing coordinates to reasonable values to avoid overflows.

Alexandre Julliard julliard at winehq.org
Mon Jul 30 14:18:51 CDT 2012


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jul 30 12:47:24 2012 +0200

gdi32: Limit line drawing coordinates to reasonable values to avoid overflows.

---

 dlls/gdi32/dibdrv/objects.c |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 026ea50..0292537 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -300,6 +300,17 @@ static inline DWORD calc_outcode(const POINT *pt, const RECT *clip)
     return out;
 }
 
+/* crop coordinates to a reasonable range to avoid overflows in calculations */
+static inline POINT crop_coords( POINT pt )
+{
+    if (pt.x >= 0x10000000 || pt.x <= -0x10000000 || pt.y >= 0x10000000 || pt.y <= -0x10000000)
+    {
+        pt.x /= 8;
+        pt.y /= 8;
+    }
+    return pt;
+}
+
 static void init_bres_params( const POINT *start, const POINT *end, bres_params *clip_params,
                               struct line_params *line_params, RECT *rect )
 {
@@ -603,6 +614,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD
     {
         bres_params clip_params;
         struct line_params line_params;
+        POINT p1 = crop_coords( *start ), p2 = crop_coords( *end );
 
         init_bres_params( start, end, &clip_params, &line_params, &rect );
         if (!get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects )) return TRUE;
@@ -611,11 +623,11 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD
             POINT clipped_start, clipped_end;
             int clip_status;
 
-            clip_status = clip_line(start, end, clipped_rects.rects + i, &clip_params, &clipped_start, &clipped_end);
+            clip_status = clip_line( &p1, &p2, clipped_rects.rects + i, &clip_params, &clipped_start, &clipped_end);
             if(clip_status)
             {
-                int m = abs(clipped_start.x - start->x);
-                int n = abs(clipped_start.y - start->y);
+                int m = abs(clipped_start.x - p1.x);
+                int n = abs(clipped_start.y - p1.y);
 
                 if (line_params.x_major)
                 {
@@ -630,7 +642,7 @@ static BOOL solid_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end, DWORD
                     line_params.length = abs( clipped_end.y - clipped_start.y ) + 1;
                 }
 
-                if (clipped_end.x == end->x && clipped_end.y == end->y) line_params.length--;
+                if (clipped_end.x == p2.x && clipped_end.y == p2.y) line_params.length--;
 
                 pdev->dib.funcs->solid_line( &pdev->dib, &clipped_start, &line_params, and, xor );
 
@@ -987,6 +999,7 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
     {
         bres_params clip_params;
         struct line_params line_params;
+        POINT p1 = crop_coords( *start ), p2 = crop_coords( *end );
 
         init_bres_params( start, end, &clip_params, &line_params, &rect );
         get_clipped_rects( &pdev->dib, &rect, pdev->clip, &clipped_rects );
@@ -994,12 +1007,12 @@ static BOOL dashed_pen_line(dibdrv_physdev *pdev, POINT *start, POINT *end)
         {
             POINT clipped_start, clipped_end;
             int clip_status;
-            clip_status = clip_line(start, end, clipped_rects.rects + i, &clip_params, &clipped_start, &clipped_end);
+            clip_status = clip_line(&p1, &p2, clipped_rects.rects + i, &clip_params, &clipped_start, &clipped_end);
 
             if(clip_status)
             {
-                int m = abs(clipped_start.x - start->x);
-                int n = abs(clipped_start.y - start->y);
+                int m = abs(clipped_start.x - p1.x);
+                int n = abs(clipped_start.y - p1.y);
 
                 pdev->dash_pos = start_pos;
 




More information about the wine-cvs mailing list