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)
This commit is contained in:
Vadim Zeitlin 2023-05-18 00:31:15 +02:00
parent e19984e2dd
commit a053e71ee6
3 changed files with 33 additions and 0 deletions

View File

@ -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:

View File

@ -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);
}

View File

@ -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