diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-10-23 10:47:30 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-10-23 16:11:01 +0200 |
commit | 36a1942bccdf63f26ea3a4497688f367083d2f0e (patch) | |
tree | 1f631cfa5917afbce33f3c5f994bb79f761a97bb /filter | |
parent | a5e9280e07deb52c2cc837f8455eee10f0244788 (diff) |
ofz#18467 check against end of buffer
Change-Id: Ibeed87e2e3af90219e7bbbd773d369c90f78a364
Reviewed-on: https://gerrit.libreoffice.org/81371
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'filter')
-rw-r--r-- | filter/source/graphicfilter/icgm/bitmap.cxx | 58 | ||||
-rw-r--r-- | filter/source/graphicfilter/icgm/bitmap.hxx | 2 |
2 files changed, 53 insertions, 7 deletions
diff --git a/filter/source/graphicfilter/icgm/bitmap.cxx b/filter/source/graphicfilter/icgm/bitmap.cxx index 12e3f25416dc..825c90243e0a 100644 --- a/filter/source/graphicfilter/icgm/bitmap.cxx +++ b/filter/source/graphicfilter/icgm/bitmap.cxx @@ -81,6 +81,7 @@ void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc ) switch ( rDesc.mnDstBitsPerPixel ) { case 1 : { + bool bOk = true; std::vector<Color> palette(2); if ( rDesc.mnLocalColorPrecision == 1 ) palette = ImplGeneratePalette( rDesc ); @@ -90,11 +91,18 @@ void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc ) ? BMCOL( mpCGM->pElement->pFillBundle->GetColor() ) : BMCOL( mpCGM->pElement->aFillBundle.GetColor() ); }; - for ( ny = 0; --nyCount ; ny++, rDesc.mpBuf += rDesc.mnScanSize ) { + for (ny = 0; bOk && --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize) { nxC = nxCount; for ( nx = 0; --nxC; nx++ ) { // this is not fast, but a one bit/pixel format is rarely used - sal_uInt8 colorIndex = static_cast<sal_uInt8>( (*( rDesc.mpBuf + (nx >> 3)) >> ((nx & 7)^7))) & 1; + const sal_uInt8* pPos = rDesc.mpBuf + (nx >> 3); + if (pPos >= rDesc.mpEndBuf) + { + SAL_WARN("filter.icgm", "buffer is too small"); + bOk = false; + break; + } + sal_uInt8 colorIndex = static_cast<sal_uInt8>((*pPos >> ((nx & 7)^7))) & 1; aBitmap.SetPixel(ny, nx, palette[colorIndex]); } } @@ -102,23 +110,40 @@ void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc ) break; case 2 : { + bool bOk = true; auto palette = ImplGeneratePalette( rDesc ); - for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) { + for (ny = 0; bOk && --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize) { nxC = nxCount; for ( nx = 0; --nxC; nx++ ) { // this is not fast, but a two bits/pixel format is rarely used - aBitmap.SetPixel(ny, nx, palette[static_cast<sal_uInt8>( (*(rDesc.mpBuf + (nx >> 2)) >> (((nx & 3)^3) << 1))) & 3]); + const sal_uInt8* pPos = rDesc.mpBuf + (nx >> 2); + if (pPos >= rDesc.mpEndBuf) + { + SAL_WARN("filter.icgm", "buffer is too small"); + bOk = false; + break; + } + aBitmap.SetPixel(ny, nx, palette[static_cast<sal_uInt8>( (*pPos >> (((nx & 3)^3) << 1))) & 3]); } } } break; case 4 : { + bool bOk = true; auto palette = ImplGeneratePalette( rDesc ); - for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) { + for (ny = 0; bOk && --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize) { nxC = nxCount; sal_uInt8* pTemp = rDesc.mpBuf; for ( nx = 0; --nxC; nx++ ) { + + if (pTemp >= rDesc.mpEndBuf) + { + SAL_WARN("filter.icgm", "buffer is too small"); + bOk = false; + break; + } + sal_uInt8 nDat = *pTemp++; aBitmap.SetPixel(ny, nx, palette[static_cast<sal_uInt8>(nDat >> 4)]); @@ -133,11 +158,20 @@ void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc ) break; case 8 : { + bool bOk = true; auto palette = ImplGeneratePalette( rDesc ); - for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) { + for (ny = 0; bOk && --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize) { sal_uInt8* pTemp = rDesc.mpBuf; nxC = nxCount; for ( nx = 0; --nxC; nx++ ) { + + if (pTemp >= rDesc.mpEndBuf) + { + SAL_WARN("filter.icgm", "buffer is too small"); + bOk = false; + break; + } + aBitmap.SetPixel(ny, nx, palette[*(pTemp++)]); } } @@ -145,11 +179,20 @@ void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc ) break; case 24 : { + bool bOk = true; Color aBitmapColor; - for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) { + for (ny = 0; bOk && --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize) { sal_uInt8* pTemp = rDesc.mpBuf; nxC = nxCount; for ( nx = 0; --nxC; nx++ ) { + + if (pTemp + 2 >= rDesc.mpEndBuf) + { + SAL_WARN("filter.icgm", "buffer is too small"); + bOk = false; + break; + } + aBitmapColor.SetRed( *pTemp++ ); aBitmapColor.SetGreen( *pTemp++ ); aBitmapColor.SetBlue( *pTemp++ ); @@ -302,6 +345,7 @@ bool CGMBitmap::ImplGetDimensions( CGMBitmapDescriptor& rDesc ) if ( rDesc.mbStatus ) { rDesc.mpBuf = mpCGM->mpSource + mpCGM->mnParaSize; // mpBuf now points to the first scanline + rDesc.mpEndBuf = mpCGM->mpEndValidSource; mpCGM->mnParaSize += rDesc.mnScanSize * rDesc.mnY; } return rDesc.mbStatus; diff --git a/filter/source/graphicfilter/icgm/bitmap.hxx b/filter/source/graphicfilter/icgm/bitmap.hxx index 2d2c12fd64fd..971a33cf071b 100644 --- a/filter/source/graphicfilter/icgm/bitmap.hxx +++ b/filter/source/graphicfilter/icgm/bitmap.hxx @@ -30,6 +30,7 @@ class CGMBitmapDescriptor { public: sal_uInt8* mpBuf; + sal_uInt8* mpEndBuf; BitmapEx mxBitmap; bool mbStatus; bool mbVMirror; @@ -47,6 +48,7 @@ class CGMBitmapDescriptor CGMBitmapDescriptor() : mpBuf(nullptr) + , mpEndBuf(nullptr) , mbStatus(false) , mbVMirror(false) , mnDstBitsPerPixel(0) |