Author: hdu
Date: Wed Jul 18 09:26:36 2012
New Revision: 1362831
URL: http://svn.apache.org/viewvc?rev=1362831&view=rev
Log:
120306# enforce finite memory consumption of loaded jpeg
Patch-by: orw
Tested-by: orw
Modified:
incubator/ooo/trunk/main/svtools/source/filter/jpeg/jpeg.cxx
Modified: incubator/ooo/trunk/main/svtools/source/filter/jpeg/jpeg.cxx
URL:
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svtools/source/filter/jpeg/jpeg.cxx?rev=1362831&r1=1362830&r2=1362831&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svtools/source/filter/jpeg/jpeg.cxx (original)
+++ incubator/ooo/trunk/main/svtools/source/filter/jpeg/jpeg.cxx Wed Jul 18
09:26:36 2012
@@ -48,6 +48,14 @@ using namespace ::com::sun::star;
#define JPEGMINREAD 512
+namespace {
+ // Arbitrary maximal size (256M) of bitmaps after they have been decoded.
+ // It is used to prevent excessive swapping due to large buffers in
+ // virtual memory.
+ // May have to be tuned if it turns out to be too large or too small.
+ static const sal_uInt64 MAX_BITMAP_BYTE_SIZE = sal_uInt64(256 * 1024 *
1024);
+}
+
// -------------
// - (C-Calls) -
// -------------
@@ -335,11 +343,25 @@ void* JPEGReader::CreateBitmap( void* pP
((JPEGCreateBitmapParam*)pParam)->nHeight );
sal_Bool bGray = ((JPEGCreateBitmapParam*)pParam)->bGray != 0;
- void* pBmpBuf = NULL;
+ void* pBmpBuf = NULL;
- if( pAcc )
- aBmp.ReleaseAccess( pAcc );
+ if( pAcc )
+ {
+ aBmp.ReleaseAccess( pAcc );
+ aBmp = Bitmap();
+ pAcc = NULL;
+ }
+ // Check if the bitmap is untypically large.
+ if (aSize.Width()<=0
+ || aSize.Height()<=0
+ || sal_uInt64(aSize.Width())*sal_uInt64(aSize.Height())*(bGray?1:3) >
MAX_BITMAP_BYTE_SIZE)
+ {
+ // Do not try to acquire resources for the large bitmap or to
+ // read the bitmap into memory.
+ return NULL;
+ }
+
if( bGray )
{
BitmapPalette aGrayPal( 256 );
@@ -354,7 +376,7 @@ void* JPEGReader::CreateBitmap( void* pP
}
else
aBmp = Bitmap( aSize, 24 );
-
+
if ( bSetLogSize )
{
unsigned long nUnit = ((JPEGCreateBitmapParam*)pParam)->density_unit;
@@ -376,8 +398,8 @@ void* JPEGReader::CreateBitmap( void* pP
pAcc = aBmp.AcquireWriteAccess();
- if( pAcc )
- {
+ if( pAcc )
+ {
long nAlignedWidth;
const sal_uLong nFormat = pAcc->GetScanlineFormat();
@@ -402,13 +424,14 @@ void* JPEGReader::CreateBitmap( void* pP
if ( pBmpBuf == 0 )
{
aBmp.ReleaseAccess( pAcc );
+ aBmp = Bitmap();
pAcc = NULL;
}
((JPEGCreateBitmapParam*)pParam)->nAlignedWidth = nAlignedWidth;
- }
+ }
- return pBmpBuf;
+ return pBmpBuf;
}
// ------------------------------------------------------------------------