diff -ru libreoffice-3.4.5.2/basebmp/source/bitmapdevice.cxx libreoffice-3.4.5.2/basebmp/source/bitmapdevice.cxx --- libreoffice-3.4.5.2/basebmp/source/bitmapdevice.cxx 2012-05-17 09:38:03.882649105 +0100 +++ libreoffice-3.4.5.2/basebmp/source/bitmapdevice.cxx 2012-05-17 09:43:38.672289060 +0100 @@ -1825,8 +1825,13 @@ // factor in bottom-up scanline order case nScanlineStride *= bTopDown ? 1 : -1; - const std::size_t nMemSize( - (nScanlineStride < 0 ? -nScanlineStride : nScanlineStride)*rSize.getY() ); + const sal_uInt32 nWidth(nScanlineStride < 0 ? -nScanlineStride : nScanlineStride); + const sal_uInt32 nHeight(rSize.getY()); + + if (nHeight && nWidth && nWidth > SAL_MAX_INT32 / nHeight) + return BitmapDeviceSharedPtr(); + + const std::size_t nMemSize(nWidth * nHeight); if( !pMem ) { diff -ru libreoffice-3.4.5.2/vcl/source/gdi/pngread.cxx libreoffice-3.4.5.2/vcl/source/gdi/pngread.cxx --- libreoffice-3.4.5.2/vcl/source/gdi/pngread.cxx 2012-05-17 09:38:37.756016605 +0100 +++ libreoffice-3.4.5.2/vcl/source/gdi/pngread.cxx 2012-05-17 09:43:59.121511933 +0100 @@ -203,6 +203,7 @@ mpScanCurrent ( NULL ), mpColorTable ( (sal_uInt8*) mpDefaultColorTable ), mnPass ( 0 ), + mbPalette( sal_False ), mbzCodecInUse ( sal_False ), mbStatus( sal_True), mbIDAT( sal_False ), @@ -306,7 +307,7 @@ nCRC32 = rtl_crc32( nCRC32, &rChunkData.aData[ 0 ], mnChunkLen ); maDataIter = rChunkData.aData.begin(); } - sal_uInt32 nCheck; + sal_uInt32 nCheck(0); mrPNGStream >> nCheck; if( nCRC32 != nCheck ) return false; @@ -348,14 +349,23 @@ // reset to the first chunk maChunkIter = maChunkSeq.begin(); - // parse the chunks + // first chunk must be IDHR + if( mbStatus && ReadNextChunk() ) + { + if (mnChunkType == PNGCHUNK_IHDR) + mbStatus = ImplReadHeader( rPreviewSizeHint ); + else + mbStatus = false; + } + + // parse the remaining chunks while( mbStatus && !mbIDAT && ReadNextChunk() ) { switch( mnChunkType ) { case PNGCHUNK_IHDR : { - mbStatus = ImplReadHeader( rPreviewSizeHint ); + mbStatus = false; //IHDR should only appear as the first chunk } break; @@ -612,14 +622,6 @@ mnScansize = static_cast< sal_uInt32 >( nScansize64 ); - // TODO: switch between both scanlines instead of copying - mpInflateInBuf = new (std::nothrow) sal_uInt8[ mnScansize ]; - mpScanCurrent = mpInflateInBuf; - mpScanPrior = new (std::nothrow) sal_uInt8[ mnScansize ]; - - if ( !mpInflateInBuf || !mpScanPrior ) - return sal_False; - // calculate target size from original size and the preview hint if( rPreviewSizeHint.Width() || rPreviewSizeHint.Height() ) { @@ -654,6 +656,21 @@ maTargetSize.Width() = (maOrigSize.Width() + mnPreviewMask) >> mnPreviewShift; maTargetSize.Height() = (maOrigSize.Height() + mnPreviewMask) >> mnPreviewShift; + //round bits up to nearest multiple of 8 and divide by 8 to get num of bytes per pixel + int nBytesPerPixel = ((mnTargetDepth + 7) & ~7)/8; + + //stupidly big, forget about it + if (maTargetSize.Width() >= SAL_MAX_INT32 / nBytesPerPixel / maTargetSize.Height()) + return sal_False; + + // TODO: switch between both scanlines instead of copying + mpInflateInBuf = new (std::nothrow) sal_uInt8[ mnScansize ]; + mpScanCurrent = mpInflateInBuf; + mpScanPrior = new (std::nothrow) sal_uInt8[ mnScansize ]; + + if ( !mpInflateInBuf || !mpScanPrior ) + return sal_False; + mpBmp = new Bitmap( maTargetSize, mnTargetDepth ); mpAcc = mpBmp->AcquireWriteAccess(); if( !mpAcc ) @@ -765,14 +786,17 @@ { if ( mnChunkLen <= 256 ) { + mbTransparent = true; mpTransTab = new sal_uInt8 [ 256 ]; rtl_fillMemory( mpTransTab, 256, 0xff ); - rtl_copyMemory( mpTransTab, &(*maDataIter), mnChunkLen ); - maDataIter += mnChunkLen; - mbTransparent = true; - // need alpha transparency if not on/off masking - for( int i = 0; i < mnChunkLen; ++i ) - bNeedAlpha |= (mpTransTab[i]!=0x00) && (mpTransTab[i]!=0xFF); + if (mnChunkLen > 0) + { + rtl_copyMemory( mpTransTab, &(*maDataIter), mnChunkLen ); + maDataIter += mnChunkLen; + // need alpha transparency if not on/off masking + for( int i = 0; i < mnChunkLen; ++i ) + bNeedAlpha |= (mpTransTab[i]!=0x00) && (mpTransTab[i]!=0xFF); + } } } break;