[PATCH] d2d1: Check the vertex count again after duplicate removal in d2d_path_geometry_triangulate().

Henri Verbeet hverbeet at codeweavers.com
Thu Sep 16 09:01:51 CDT 2021


As the test shows, we can create geometries that have less than two vertices
after eliminating duplicates. Calling d2d_cdt_triangulate() on those would
lead to infinite recursion. In principle we could now get rid of the original
vertex count check, but it seems cheap enough that it's worth keeping in order
to avoid some unnecessary work in the somewhat more common case that we have
less than three vertices before duplicate removal.

Based on a patch by Changsheng Chen.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d2d1/geometry.c   |  7 +++++++
 dlls/d2d1/tests/d2d1.c | 22 ++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index 6da93de3eb4..c7d0d94f1ad 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -2061,6 +2061,13 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry)
         }
     }
 
+    if (vertex_count < 3)
+    {
+        WARN("Geometry has %lu vertices after eliminating duplicates.\n", (long)vertex_count);
+        heap_free(vertices);
+        return S_OK;
+    }
+
     geometry->fill.vertices = vertices;
     geometry->fill.vertex_count = vertex_count;
 
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 3e2eda8a4a4..d38d49cd139 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -3268,6 +3268,28 @@ static void test_path_geometry(BOOL d3d11)
 
     ID2D1PathGeometry_Release(geometry);
 
+    /* Degenerate figure. */
+    hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
+    ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
+    hr = ID2D1PathGeometry_Open(geometry, &sink);
+    ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
+    set_point(&point, 123.0f, 456.0f);
+    ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
+    quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
+    quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
+    quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
+    ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
+    hr = ID2D1GeometrySink_Close(sink);
+    ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
+    ID2D1GeometrySink_Release(sink);
+    hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
+    ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
+    ok(count == 1, "Got unexpected figure count %u.\n", count);
+    hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
+    ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
+    ok(count == 4, "Got unexpected segment count %u.\n", count);
+    ID2D1PathGeometry_Release(geometry);
+
     /* Close right after Open(). */
     hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
     ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
-- 
2.20.1




More information about the wine-devel mailing list