From 74413a989ffd3b246f4b42b424055ceeff0dcaa9 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 9 Nov 2021 14:32:04 +0900 Subject: [PATCH] common paint: fix a memory leak. delete dangling object properly in the corner case. Unfortunately, this brings to correct the capi test cases. we assume the paints is deleted whenever its result is successful or not. @Issue: https://github.com/Samsung/thorvg/issues/995 --- src/lib/tvgPaint.cpp | 4 +++- test/capi/capiPaint.cpp | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index f52a0ffe..60e3bfdd 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -353,7 +353,9 @@ Paint* Paint::duplicate() const noexcept Result Paint::composite(std::unique_ptr target, CompositeMethod method) noexcept { - if (pImpl->composite(target.release(), method)) return Result::Success; + auto p = target.release(); + if (pImpl->composite(p, method)) return Result::Success; + if (p) delete(p); return Result::InvalidArguments; } diff --git a/test/capi/capiPaint.cpp b/test/capi/capiPaint.cpp index d8feff2b..8cbb102f 100644 --- a/test/capi/capiPaint.cpp +++ b/test/capi/capiPaint.cpp @@ -216,18 +216,24 @@ TEST_CASE("Paint Clip Path Composite Method", "[capiPaint]") REQUIRE(target); REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_paint_set_composite_method(paint, target, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT); + + Tvg_Paint* target2 = tvg_shape_new(); + REQUIRE(target2); + REQUIRE(tvg_paint_set_composite_method(paint, target2, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT); REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_CLIP_PATH) == TVG_RESULT_INVALID_ARGUMENT); - REQUIRE(tvg_paint_set_composite_method(paint, target, TVG_COMPOSITE_METHOD_CLIP_PATH) == TVG_RESULT_SUCCESS); - const Tvg_Paint* target2 = nullptr; + Tvg_Paint* target3 = tvg_shape_new(); + REQUIRE(target3); + REQUIRE(tvg_paint_set_composite_method(paint, target3, TVG_COMPOSITE_METHOD_CLIP_PATH) == TVG_RESULT_SUCCESS); + + const Tvg_Paint* target4 = nullptr; Tvg_Composite_Method method = TVG_COMPOSITE_METHOD_NONE; REQUIRE(tvg_paint_get_composite_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT); - REQUIRE(tvg_paint_get_composite_method(paint, &target2, NULL) == TVG_RESULT_INVALID_ARGUMENT); - REQUIRE(tvg_paint_get_composite_method(paint, &target2, &method) == TVG_RESULT_SUCCESS); + REQUIRE(tvg_paint_get_composite_method(paint, &target4, NULL) == TVG_RESULT_INVALID_ARGUMENT); + REQUIRE(tvg_paint_get_composite_method(paint, &target4, &method) == TVG_RESULT_SUCCESS); REQUIRE(method == TVG_COMPOSITE_METHOD_CLIP_PATH); - REQUIRE(target == target2); + REQUIRE(target3 == target4); REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS); }