diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-01-19 16:56:34 +0000 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2017-01-26 17:01:24 +0000 |
commit | 64c128b0d3467613e862673a7f6ad4750a7ebdaa (patch) | |
tree | f3e8e9cccc33200e9d7ca89fa0ff1984e8423bd4 | |
parent | Resolves: tdf#104675 ScConditionalFormat ranges needed to start listening (diff) | |
download | core-64c128b0d3467613e862673a7f6ad4750a7ebdaa.tar.gz core-64c128b0d3467613e862673a7f6ad4750a7ebdaa.zip |
Resolves: ofz#424 guard against broken dxary length
Reviewed-on: https://gerrit.libreoffice.org/33320
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
(cherry picked from commit 336764ad6b8f4d88ac579684c905c88c8c630bcd)
Change-Id: Ia2569e963edd75cd6c27399d33e73bafe8b3f073
Reviewed-on: https://gerrit.libreoffice.org/33536
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Reviewed-by: Eike Rathke <erack@redhat.com>
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r-- | vcl/source/gdi/svmconverter.cxx | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/vcl/source/gdi/svmconverter.cxx b/vcl/source/gdi/svmconverter.cxx index 11491ba1d562..633171c4fdfb 100644 --- a/vcl/source/gdi/svmconverter.cxx +++ b/vcl/source/gdi/svmconverter.cxx @@ -906,6 +906,7 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) OUString aStr(OStringToOUString(aByteStr, eActualCharSet)); std::unique_ptr<long[]> pDXAry; + sal_Int32 nDXAryLen = 0; if (nAryLen > 0) { const size_t nMinRecordSize = sizeof(sal_Int32); @@ -919,36 +920,49 @@ void SVMConverter::ImplConvertFromSVM1( SvStream& rIStm, GDIMetaFile& rMtf ) sal_Int32 nStrLen( aStr.getLength() ); - pDXAry.reset(new long[ std::max( nAryLen, nStrLen ) ]); + nDXAryLen = std::max(nAryLen, nStrLen); + pDXAry.reset(new long[nDXAryLen]); - for (sal_Int32 j = 0; j < nAryLen; ++j) - rIStm.ReadInt32( nTmp ), pDXAry[ j ] = nTmp; - - // #106172# Add last DX array elem, if missing - if( nAryLen != nStrLen ) + if (nDXAryLen < nLen) + { + //MetaTextArrayAction ctor expects pDXAry to be >= nLen if set, so if this can't + //be achieved, don't read it, it's utterly broken. + SAL_WARN("vcl.gdi", "dxary too short, discarding completely"); + rIStm.SeekRel(sizeof(sal_Int32) * nDXAryLen); + nLen = 0; + nIndex = 0; + } + else { - if( nAryLen+1 == nStrLen ) + for (sal_Int32 j = 0; j < nAryLen; ++j) + rIStm.ReadInt32( nTmp ), pDXAry[ j ] = nTmp; + + // #106172# Add last DX array elem, if missing + if( nAryLen != nStrLen ) { - std::unique_ptr<long[]> pTmpAry(new long[nStrLen]); - - aFontVDev->GetTextArray( aStr, pTmpAry.get(), nIndex, nLen ); - - // now, the difference between the - // last and the second last DX array - // is the advancement for the last - // glyph. Thus, to complete our meta - // action's DX array, just add that - // difference to last elem and store - // in very last. - if( nStrLen > 1 ) - pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ]; + if( nAryLen+1 == nStrLen ) + { + std::unique_ptr<long[]> pTmpAry(new long[nStrLen]); + + aFontVDev->GetTextArray( aStr, pTmpAry.get(), nIndex, nLen ); + + // now, the difference between the + // last and the second last DX array + // is the advancement for the last + // glyph. Thus, to complete our meta + // action's DX array, just add that + // difference to last elem and store + // in very last. + if( nStrLen > 1 ) + pDXAry[ nStrLen-1 ] = pDXAry[ nStrLen-2 ] + pTmpAry[ nStrLen-1 ] - pTmpAry[ nStrLen-2 ]; + else + pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0 + } + #ifdef DBG_UTIL else - pDXAry[ nStrLen-1 ] = pTmpAry[ nStrLen-1 ]; // len=1: 0th position taken to be 0 + OSL_FAIL("More than one DX array element missing on SVM import"); + #endif } - #ifdef DBG_UTIL - else - OSL_FAIL("More than one DX array element missing on SVM import"); - #endif } } if ( nUnicodeCommentActionNumber == i ) |