diff options
author | Herbert Dürr <hdu@apache.org> | 2012-07-18 08:40:50 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-05-10 14:03:53 +0100 |
commit | a9129e49e23e2a8d0ee9b92e00c2bddb39395d4e (patch) | |
tree | 90a93df1a37e9647cf125772a814787d7a8540d8 | |
parent | 60c1369dc00270c1bcc0d037d3c04895b6bc0c47 (diff) |
Related: #i120306# better input checks in WinSalBitmap::ImplCreateDIB()
Patch-by: hdu, orw
(cherry picked from commit 7b6990763f759f2de1902f8d22a22eb8e66797f7)
Conflicts:
vcl/win/source/gdi/salbmp.cxx
Change-Id: I106efb3960cb99367d2ecefb8bcae006f389e271
Corrected static_cast which does not work on Win compiler
reinterpret cas needed (base classes are not related)
(cherry picked from commit 99e4d3a57f88f71c47f1e519bde13080f0df3041)
Change-Id: I02fc89d1ab346231985c68d63d9710c036d2ab2a
-rw-r--r-- | vcl/win/source/gdi/salbmp.cxx | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx index 7b5f7bbf3790..0c89359c301f 100644 --- a/vcl/win/source/gdi/salbmp.cxx +++ b/vcl/win/source/gdi/salbmp.cxx @@ -329,42 +329,52 @@ HGLOBAL WinSalBitmap::ImplCreateDIB( const Size& rSize, sal_uInt16 nBits, const HGLOBAL hDIB = 0; - if ( rSize.Width() && rSize.Height() ) + if( rSize.Width() <= 0 || rSize.Height() <= 0 ) + return hDIB; + + // calculate bitmap size in Bytes + const sal_uLong nAlignedWidth4Bytes = AlignedWidth4Bytes( nBits * rSize.Width() ); + const sal_uLong nImageSize = nAlignedWidth4Bytes * rSize.Height(); + bool bOverflow = (nImageSize / nAlignedWidth4Bytes) != rSize.Height(); + if( bOverflow ) + return hDIB; + + // allocate bitmap memory including header and palette + const sal_uInt16 nColors = (nBits <= 8) ? (1 << nBits) : 0; + const sal_uLong nHeaderSize = sizeof( BITMAPINFOHEADER ) + nColors * sizeof( RGBQUAD ); + bOverflow = (nHeaderSize + nImageSize) < nImageSize; + if( bOverflow ) + return hDIB; + + hDIB = GlobalAlloc( GHND, nHeaderSize + nImageSize ); + if( !hDIB ) + return hDIB; + + PBITMAPINFO pBI = static_cast<PBITMAPINFO>( GlobalLock( hDIB ) ); + PBITMAPINFOHEADER pBIH = reinterpret_cast<PBITMAPINFOHEADER>( pBI ); + + pBIH->biSize = sizeof( BITMAPINFOHEADER ); + pBIH->biWidth = rSize.Width(); + pBIH->biHeight = rSize.Height(); + pBIH->biPlanes = 1; + pBIH->biBitCount = nBits; + pBIH->biCompression = BI_RGB; + pBIH->biSizeImage = nImageSize; + pBIH->biXPelsPerMeter = 0; + pBIH->biYPelsPerMeter = 0; + pBIH->biClrUsed = 0; + pBIH->biClrImportant = 0; + + if( nColors ) { - const sal_uLong nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height(); - const sal_uInt16 nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0; - - hDIB = GlobalAlloc( GHND, sizeof( BITMAPINFOHEADER ) + nColors * sizeof( RGBQUAD ) + nImageSize ); - - if( hDIB ) - { - PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB ); - PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI; - - pBIH->biSize = sizeof( BITMAPINFOHEADER ); - pBIH->biWidth = rSize.Width(); - pBIH->biHeight = rSize.Height(); - pBIH->biPlanes = 1; - pBIH->biBitCount = nBits; - pBIH->biCompression = BI_RGB; - pBIH->biSizeImage = nImageSize; - pBIH->biXPelsPerMeter = 0; - pBIH->biYPelsPerMeter = 0; - pBIH->biClrUsed = 0; - pBIH->biClrImportant = 0; - - if ( nColors ) - { - const sal_uInt16 nMinCount = std::min( nColors, rPal.GetEntryCount() ); - - if( nMinCount ) - memcpy( pBI->bmiColors, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGBQUAD ) ); - } - - GlobalUnlock( hDIB ); - } + // copy the palette entries if any + const sal_uInt16 nMinCount = std::min( nColors, rPal.GetEntryCount() ); + if( nMinCount ) + memcpy( pBI->bmiColors, rPal.ImplGetColorBuffer(), nMinCount * sizeof(RGBQUAD) ); } + GlobalUnlock( hDIB ); + return hDIB; } |