Avoid integer overflow when computing image data size in wxImage::Create()
See #19326 Co-Authored-By: David Costanzo <david_costanzo@yahoo.com>
This commit is contained in:
@@ -191,6 +191,8 @@ set(TEST_GUI_DATA
|
|||||||
image/toucan_dis_240.png
|
image/toucan_dis_240.png
|
||||||
image/toucan_grey.png
|
image/toucan_grey.png
|
||||||
image/toucan_mono_255_255_255.png
|
image/toucan_mono_255_255_255.png
|
||||||
|
image/width-times-height-overflow.bmp
|
||||||
|
image/width_height_32_bit_overflow.pgm
|
||||||
intl/ja/internat.mo
|
intl/ja/internat.mo
|
||||||
intl/ja/internat.po
|
intl/ja/internat.po
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -156,15 +156,22 @@ bool wxImage::Create( int width, int height, bool clear )
|
|||||||
{
|
{
|
||||||
UnRef();
|
UnRef();
|
||||||
|
|
||||||
m_refData = new wxImageRefData();
|
if (width <= 0 || height <= 0)
|
||||||
|
|
||||||
M_IMGDATA->m_data = (unsigned char *) malloc( width*height*3 );
|
|
||||||
if (!M_IMGDATA->m_data)
|
|
||||||
{
|
|
||||||
UnRef();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
|
const unsigned long long size = (unsigned long long)width * height * 3;
|
||||||
|
|
||||||
|
// In theory, 64-bit architectures could handle larger sizes,
|
||||||
|
// but wxImage code is riddled with int-based arithmetic which will overflow
|
||||||
|
if (size > INT_MAX)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char* p = (unsigned char*)malloc(size_t(size));
|
||||||
|
if (p == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_refData = new wxImageRefData;
|
||||||
|
M_IMGDATA->m_data = p;
|
||||||
M_IMGDATA->m_width = width;
|
M_IMGDATA->m_width = width;
|
||||||
M_IMGDATA->m_height = height;
|
M_IMGDATA->m_height = height;
|
||||||
M_IMGDATA->m_ok = true;
|
M_IMGDATA->m_ok = true;
|
||||||
|
|||||||
@@ -565,7 +565,7 @@ data:
|
|||||||
|
|
||||||
data-images:
|
data-images:
|
||||||
@mkdir -p image
|
@mkdir -p image
|
||||||
@for f in 8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png; do \
|
@for f in 8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png width-times-height-overflow.bmp width_height_32_bit_overflow.pgm; do \
|
||||||
if test ! -f image/$$f -a ! -d image/$$f ; \
|
if test ! -f image/$$f -a ! -d image/$$f ; \
|
||||||
then x=yep ; \
|
then x=yep ; \
|
||||||
else x=`find $(srcdir)/image/$$f -newer image/$$f -print` ; \
|
else x=`find $(srcdir)/image/$$f -newer image/$$f -print` ; \
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ private:
|
|||||||
CPPUNIT_TEST( BMPFlippingAndRLECompression );
|
CPPUNIT_TEST( BMPFlippingAndRLECompression );
|
||||||
CPPUNIT_TEST( ScaleCompare );
|
CPPUNIT_TEST( ScaleCompare );
|
||||||
CPPUNIT_TEST( CreateBitmapFromCursor );
|
CPPUNIT_TEST( CreateBitmapFromCursor );
|
||||||
CPPUNIT_TEST( MalformedBMP );
|
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
void LoadFromSocketStream();
|
void LoadFromSocketStream();
|
||||||
@@ -120,7 +119,6 @@ private:
|
|||||||
void BMPFlippingAndRLECompression();
|
void BMPFlippingAndRLECompression();
|
||||||
void ScaleCompare();
|
void ScaleCompare();
|
||||||
void CreateBitmapFromCursor();
|
void CreateBitmapFromCursor();
|
||||||
void MalformedBMP();
|
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(ImageTestCase);
|
wxDECLARE_NO_COPY_CLASS(ImageTestCase);
|
||||||
};
|
};
|
||||||
@@ -1528,25 +1526,52 @@ void ImageTestCase::CreateBitmapFromCursor()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function assumes that the file is malformed in a way that it cannot
|
// This function assumes that the file is malformed in a way that it cannot
|
||||||
// be loaded. If the file is malformed such that wxImage can salvage part
|
// be loaded but that doesn't fail a wxCHECK.
|
||||||
// of it, then CompareBMPImage should be called instead.
|
static void LoadMalformedImage(const wxString& file, wxBitmapType type)
|
||||||
static void LoadMalformedBMP(const wxString& file)
|
|
||||||
{
|
{
|
||||||
wxImage image(file);
|
// If the file doesn't exist, it's a test bug.
|
||||||
WX_ASSERT_MESSAGE
|
// (The product code would fail but for the wrong reason.)
|
||||||
(
|
INFO("Checking that image exists: " << file);
|
||||||
("wxImage::isOk() returned true after loading \"%s\"", file),
|
REQUIRE(wxFileExists(file));
|
||||||
!image.IsOk()
|
|
||||||
);
|
// Load the image, expecting a failure.
|
||||||
|
wxImage image;
|
||||||
|
INFO("Loading malformed image: " << file);
|
||||||
|
REQUIRE(!image.LoadFile(file, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageTestCase::MalformedBMP()
|
// This function assumes that the file is malformed in a way that wxImage
|
||||||
|
// fails a wxCHECK when trying to load it.
|
||||||
|
static void LoadMalformedImageWithException(const wxString& file,
|
||||||
|
wxBitmapType type)
|
||||||
{
|
{
|
||||||
LoadMalformedBMP("image/8bpp-colorsused-negative.bmp");
|
// If the file doesn't exist, it's a test bug.
|
||||||
LoadMalformedBMP("image/8bpp-colorsused-large.bmp");
|
// (The product code would fail but for the wrong reason.)
|
||||||
|
INFO("Checking that image exists: " << file);
|
||||||
|
REQUIRE(wxFileExists(file));
|
||||||
|
|
||||||
|
wxImage image;
|
||||||
|
INFO("Loading malformed image: " << file);
|
||||||
|
#ifdef __WXDEBUG__
|
||||||
|
REQUIRE_THROWS(image.LoadFile(file, type));
|
||||||
|
#else
|
||||||
|
REQUIRE(!image.LoadFile(file, type));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //wxUSE_IMAGE
|
TEST_CASE("wxImage::BMP", "[image][bmp]")
|
||||||
|
{
|
||||||
|
SECTION("Load malformed bitmaps")
|
||||||
|
{
|
||||||
|
LoadMalformedImage("image/8bpp-colorsused-negative.bmp",
|
||||||
|
wxBITMAP_TYPE_BMP);
|
||||||
|
LoadMalformedImage("image/8bpp-colorsused-large.bmp",
|
||||||
|
wxBITMAP_TYPE_BMP);
|
||||||
|
|
||||||
|
LoadMalformedImageWithException("image/width-times-height-overflow.bmp",
|
||||||
|
wxBITMAP_TYPE_BMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("wxImage::Paste", "[image][paste]")
|
TEST_CASE("wxImage::Paste", "[image][paste]")
|
||||||
{
|
{
|
||||||
@@ -2234,6 +2259,20 @@ TEST_CASE("wxImage::XPM", "[image][xpm]")
|
|||||||
CHECK( wxIcon(dummy_xpm).IsOk() );
|
CHECK( wxIcon(dummy_xpm).IsOk() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("wxImage::PNM", "[image][pnm]")
|
||||||
|
{
|
||||||
|
#if wxUSE_PNM
|
||||||
|
wxImage::AddHandler(new wxPNMHandler);
|
||||||
|
|
||||||
|
SECTION("width*height*3 overflow")
|
||||||
|
{
|
||||||
|
// wxImage should reject the file as malformed (wxTrac#19326)
|
||||||
|
LoadMalformedImageWithException("image/width_height_32_bit_overflow.pgm",
|
||||||
|
wxBITMAP_TYPE_PNM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("wxImage::ChangeColours", "[image]")
|
TEST_CASE("wxImage::ChangeColours", "[image]")
|
||||||
{
|
{
|
||||||
wxImage original;
|
wxImage original;
|
||||||
@@ -2298,3 +2337,5 @@ TEST_CASE("wxImage::SizeLimits", "[image]")
|
|||||||
/*
|
/*
|
||||||
TODO: add lots of more tests to wxImage functions
|
TODO: add lots of more tests to wxImage functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#endif //wxUSE_IMAGE
|
||||||
|
|||||||
BIN
tests/image/width-times-height-overflow.bmp
Normal file
BIN
tests/image/width-times-height-overflow.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
2395
tests/image/width_height_32_bit_overflow.pgm
Normal file
2395
tests/image/width_height_32_bit_overflow.pgm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -555,7 +555,7 @@ data:
|
|||||||
|
|
||||||
data-images:
|
data-images:
|
||||||
if not exist image mkdir image
|
if not exist image mkdir image
|
||||||
for %%f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png) do if not exist image\%%f copy .\image\%%f image
|
for %%f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png width-times-height-overflow.bmp width_height_32_bit_overflow.pgm) do if not exist image\%%f copy .\image\%%f image
|
||||||
|
|
||||||
fr:
|
fr:
|
||||||
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
||||||
|
|||||||
@@ -989,7 +989,7 @@ data:
|
|||||||
|
|
||||||
data-images:
|
data-images:
|
||||||
if not exist image mkdir image
|
if not exist image mkdir image
|
||||||
for %f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png) do if not exist image\%f copy .\image\%f image
|
for %f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png width-times-height-overflow.bmp width_height_32_bit_overflow.pgm) do if not exist image\%f copy .\image\%f image
|
||||||
|
|
||||||
fr:
|
fr:
|
||||||
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
||||||
|
|||||||
@@ -401,6 +401,9 @@
|
|||||||
toucan_dis_240.png
|
toucan_dis_240.png
|
||||||
toucan_grey.png
|
toucan_grey.png
|
||||||
toucan_mono_255_255_255.png
|
toucan_mono_255_255_255.png
|
||||||
|
|
||||||
|
width-times-height-overflow.bmp
|
||||||
|
width_height_32_bit_overflow.pgm
|
||||||
</files>
|
</files>
|
||||||
</wx-data>
|
</wx-data>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user