diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-01-19 16:56:34 +0000 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2017-02-08 11:56:05 +0100 |
commit | 1b534aa6ab9267701af3c8c7d5c523cd6fd3ccc3 (patch) | |
tree | b43e8ec1daa6ef7635df968074fe30e3627cf1d4 /vcl/source | |
parent | 0353bc884e833af32629a2a1a1c4725c8d0aecae (diff) |
Resolves: ofz#424 guard against broken dxary length
ofz#424 vcl: reset nLen too
(cherry picked from commit 7f5a10a3aaf8b48156aeab168afb7648dae1e020)
Change-Id: Ia2569e963edd75cd6c27399d33e73bafe8b3f073
Reviewed-on: https://gerrit.libreoffice.org/33321
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/gdi/cvtsvm.cxx | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/vcl/source/gdi/cvtsvm.cxx b/vcl/source/gdi/cvtsvm.cxx index 1b1e57fd6fe2..75e63c74a151 100644 --- a/vcl/source/gdi/cvtsvm.cxx +++ b/vcl/source/gdi/cvtsvm.cxx @@ -905,6 +905,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); @@ -918,36 +919,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 ) |