From a053e71ee6569d5e5dde163948c159d556705b06 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 18 May 2023 00:31:15 +0200 Subject: [PATCH] Fix lack of unsharing in wxImage::Clear() Calling Clear() wrongly modified any other wxImage objects reusing the same data. Fix this by adding the missing call to AllocExclusive() to this function and also add a check for the image validity which was missing there as well ever since this function was added back in fc3762b5fc (add wxImage::Clear (patch by troelsk); closes #10141, 2009-01-09). Also add a unit test. See #23553. (cherry picked from commit 92664881fed59ffe3650886d6ea215e75d262981) --- docs/changes.txt | 1 + src/common/image.cpp | 4 ++++ tests/image/image.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index baa5eafe5f..258363eb35 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -253,6 +253,7 @@ All (GUI): - Fix entering dates in wxGenericDatePicker in nb_NO and other locales using names for the months in short date format (#23310). - Fix wx-config output when using NanoSVG library (#23373). +- Fix bug modifying shared images in wxImage::Clear() (#23555). wxGTK: diff --git a/src/common/image.cpp b/src/common/image.cpp index a449b60930..321578412f 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -227,6 +227,10 @@ void wxImage::Destroy() void wxImage::Clear(unsigned char value) { + wxCHECK_RET( IsOk(), wxT("invalid image") ); + + AllocExclusive(); + memset(M_IMGDATA->m_data, value, M_IMGDATA->m_width*M_IMGDATA->m_height*3); } diff --git a/tests/image/image.cpp b/tests/image/image.cpp index 56929d3956..c0480811c5 100644 --- a/tests/image/image.cpp +++ b/tests/image/image.cpp @@ -2305,6 +2305,34 @@ TEST_CASE("wxImage::ChangeColours", "[image]") CHECK_THAT(test, RGBSameAs(expected)); } +TEST_CASE("wxImage::Clear", "[image]") +{ + wxImage image(2, 2); + image.SetRGB(0, 0, 0xff, 0x00, 0x00); + image.SetRGB(0, 1, 0x00, 0xff, 0x00); + image.SetRGB(1, 0, 0x00, 0x00, 0xff); + image.SetRGB(1, 1, 0xff, 0xff, 0xff); + + wxImage image2(image); + + // Check that the image has the expected red component values initially. + CHECK( image2.GetRed(0, 0) == 0xff ); + CHECK( image2.GetRed(0, 1) == 0x00 ); + CHECK( image2.GetRed(1, 0) == 0x00 ); + CHECK( image2.GetRed(1, 1) == 0xff ); + + // Check that the image got cleared. + image2.Clear(); + CHECK( image2.GetRed(0, 0) == 0x00 ); + CHECK( image2.GetRed(0, 1) == 0x00 ); + CHECK( image2.GetRed(1, 0) == 0x00 ); + CHECK( image2.GetRed(1, 1) == 0x00 ); + + // Check that the original image didn't change (see #23553). + CHECK( image.GetRed(0, 0) == 0xff ); + CHECK( image.GetRed(1, 1) == 0xff ); +} + TEST_CASE("wxImage::SizeLimits", "[image]") { #if SIZEOF_VOID_P == 8