From 823607796ba766756e23d8f3b0746ca6f12bba95 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 7 Feb 2023 12:07:42 +0100 Subject: [PATCH] Additional safety around wks bitmaps Invalid files can create large problems for unloaded PNG data Fixes https://gitlab.com/kicad/code/kicad/issues/13801 --- common/drawing_sheet/drawing_sheet_parser.cpp | 13 ++++++++++++- common/drawing_sheet/ds_data_item.cpp | 3 +++ common/drawing_sheet/ds_data_model_io.cpp | 4 ++++ common/drawing_sheet/ds_draw_item.cpp | 9 ++++++--- common/drawing_sheet/ds_painter.cpp | 7 +++++++ common/gal/opengl/opengl_gal.cpp | 7 ++++++- 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/common/drawing_sheet/drawing_sheet_parser.cpp b/common/drawing_sheet/drawing_sheet_parser.cpp index fa1467eaab..1cdb1e9acc 100644 --- a/common/drawing_sheet/drawing_sheet_parser.cpp +++ b/common/drawing_sheet/drawing_sheet_parser.cpp @@ -240,7 +240,18 @@ void DRAWING_SHEET_PARSER::Parse( DS_DATA_MODEL* aLayout ) case T_bitmap: item = new DS_DATA_ITEM_BITMAP( NULL ); parseBitmap( (DS_DATA_ITEM_BITMAP*) item ); - aLayout->Append( item ); + + // Drop invalid bitmaps + if( static_cast( item )->m_ImageBitmap->GetOriginalImageData() ) + { + aLayout->Append( item ); + } + else + { + delete static_cast( item )->m_ImageBitmap; + delete item; + } + break; case T_tbtext: diff --git a/common/drawing_sheet/ds_data_item.cpp b/common/drawing_sheet/ds_data_item.cpp index abbeab5d8b..a5f32790b0 100644 --- a/common/drawing_sheet/ds_data_item.cpp +++ b/common/drawing_sheet/ds_data_item.cpp @@ -739,6 +739,9 @@ void DS_DATA_ITEM_BITMAP::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::V m_ImageBitmap->SetPixelSizeIu( pix_size_iu ); } + if( !m_ImageBitmap->GetOriginalImageData() ) + return; + m_drawItems.clear(); for( int j = 0; j < m_RepeatCount; j++ ) diff --git a/common/drawing_sheet/ds_data_model_io.cpp b/common/drawing_sheet/ds_data_model_io.cpp index 2742043777..aacc1dbb9a 100644 --- a/common/drawing_sheet/ds_data_model_io.cpp +++ b/common/drawing_sheet/ds_data_model_io.cpp @@ -397,6 +397,10 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_POLYGONS* aItem, int aNestLevel ) co void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_BITMAP* aItem, int aNestLevel ) const { + // Don't save empty images + if( !aItem->m_ImageBitmap->GetOriginalImageData() ) + return; + m_out->Print( aNestLevel, "(bitmap" ); m_out->Print( 0, " (name %s)", m_out->Quotew( aItem->m_Name ).c_str() ); formatCoordinate( "pos", aItem->m_Pos ); diff --git a/common/drawing_sheet/ds_draw_item.cpp b/common/drawing_sheet/ds_draw_item.cpp index 1b2d27108e..e7485f8ac6 100644 --- a/common/drawing_sheet/ds_draw_item.cpp +++ b/common/drawing_sheet/ds_draw_item.cpp @@ -435,11 +435,14 @@ void DS_DRAW_ITEM_BITMAP::PrintWsItem( const RENDER_SETTINGS* aSettings, const V const BOX2I DS_DRAW_ITEM_BITMAP::GetBoundingBox() const { const DS_DATA_ITEM_BITMAP* bitmap = static_cast( m_peer ); - VECTOR2I bm_size = bitmap->m_ImageBitmap->GetSize(); BOX2I bbox; - bbox.SetSize( bm_size ); - bbox.SetOrigin( m_pos.x - bm_size.x / 2, m_pos.y - bm_size.y / 2 ); + if( bitmap && bitmap->m_ImageBitmap ) + { + VECTOR2I bm_size = bitmap->m_ImageBitmap->GetSize(); + bbox.SetSize( bm_size ); + bbox.SetOrigin( m_pos.x - bm_size.x / 2, m_pos.y - bm_size.y / 2 ); + } return bbox; } diff --git a/common/drawing_sheet/ds_painter.cpp b/common/drawing_sheet/ds_painter.cpp index 7369762c2d..39f3056106 100644 --- a/common/drawing_sheet/ds_painter.cpp +++ b/common/drawing_sheet/ds_painter.cpp @@ -282,6 +282,13 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_BITMAP* aItem, int aLayer ) con VECTOR2D position = aItem->GetPosition(); m_gal->Translate( position ); + // If we've failed to read the bitmap data, don't try to draw it + if( !( bitmap && bitmap->m_ImageBitmap + && bitmap->m_ImageBitmap->GetImageData() ) ) + { + return; + } + // When the image scale factor is not 1.0, we need to modify the actual scale // as the image scale factor is similar to a local zoom double img_scale = bitmap->m_ImageBitmap->GetScale(); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index fa27f9e102..3663707c3a 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -159,7 +159,12 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap ) { CACHED_BITMAP bmp; - const wxImage& imgData = *aBitmap->GetOriginalImageData(); + const wxImage* imgPtr = aBitmap->GetOriginalImageData(); + + if( !imgPtr ) + return std::numeric_limits< GLuint >::max(); + + const wxImage& imgData = *imgPtr; bmp.w = imgData.GetSize().x; bmp.h = imgData.GetSize().y;