[PATCH 1/2] gdiplus/tests: New path that can cause stack overflow in GdipFlattenPath.

Robert Feuerbach rjfeuerbach at gmail.com
Fri Feb 4 09:58:47 CST 2022


A bezier curve found in an application has caused endless recursive
calls to flatten_bezier due to float point precision limitations in
the flatness test.  This curve has been added to the graphicpath.c
test to check for the resulting stack overflow error.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52492
Signed-off-by: Robert Feuerbach <rjfeuerbach at gmail.com>
---
 dlls/gdiplus/tests/graphicspath.c | 55 ++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c
index 07e6dd166ad..36508776ed3 100644
--- a/dlls/gdiplus/tests/graphicspath.c
+++ b/dlls/gdiplus/tests/graphicspath.c
@@ -1253,6 +1253,58 @@ static void test_flatten(void)
     GdipDeletePath(path);
 }
 
+static void test_flatten2(void)
+{
+    GpStatus status;
+    GpPath *path;
+    INT count;
+    
+    status = GdipCreatePath(0, &path);
+    expect(Ok, status);
+    status = GdipStartPathFigure(path);
+    expect(Ok, status);
+    /* path seen in the wild that caused a stack overflow */
+    /* low-precision points that can cause a crash */
+    status = GdipAddPathBezier(path,
+			       154.950806, 33.391144,
+			       221.586075, 15.536285,
+			       291.747314, 15.536285,
+			       358.382568, 33.391144);
+    expect(Ok, status);
+    status = GdipAddPathBezier(path,
+			       256.666809, 412.999512,
+			       256.666718, 412.999481,
+			       256.666656, 412.999481,
+			       256.666565, 412.999512);
+    expect(Ok, status);
+    status = GdipClosePathFigure(path);
+    expect(Ok, status);
+    trace("Flattening good and problematic bezier curves\n");
+    status = GdipFlattenPath(path, NULL, 1.0);
+
+    /* now redo with hexadecimal floats to replicate the points exactly */
+    status = GdipResetPath(path);
+    expect(Ok, status);
+    status = GdipAddPathBezier(path,
+			       0x1.35e6d00000000p+7, 0x1.0b21100000000p+5,
+			       0x1.bb2c120000000p+7, 0x1.f129400000000p+3,
+			       0x1.23bf500000000p+8, 0x1.f129400000000p+3,
+			       0x1.6661f00000000p+8, 0x1.0b21100000000p+5);
+    expect(Ok, status);
+    status = GdipAddPathBezier(path,
+			       0x1.00aab40000000p+8, 0x1.9cffe00000000p+8,
+			       0x1.00aaae0000000p+8, 0x1.9cffde0000000p+8,
+			       0x1.00aaaa0000000p+8, 0x1.9cffde0000000p+8,
+			       0x1.00aaa40000000p+8, 0x1.9cffe00000000p+8);
+    expect(Ok, status);
+    status = GdipClosePathFigure(path);
+    expect(Ok, status);
+    trace("Flattening precise copied problematic curves\n");
+    status = GdipFlattenPath(path, NULL, 1.0);
+    
+    GdipDeletePath(path);
+}
+
 static path_test_t widenline_path[] = {
     {5.0, 5.0,   PathPointTypeStart, 0, 0}, /*0*/
     {50.0, 5.0,  PathPointTypeLine,  0, 0}, /*1*/
@@ -1900,6 +1952,7 @@ START_TEST(graphicspath)
     test_widen_cap();
     test_isvisible();
     test_empty_rect();
-
+    test_flatten2();
+    
     GdiplusShutdown(gdiplusToken);
 }
-- 
2.32.0 (Apple Git-132)




More information about the wine-devel mailing list