summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vcl/source/font/fontcharmap.cxx32
1 files changed, 28 insertions, 4 deletions
diff --git a/vcl/source/font/fontcharmap.cxx b/vcl/source/font/fontcharmap.cxx
index a375f98fa14f..f9aa5ded6963 100644
--- a/vcl/source/font/fontcharmap.cxx
+++ b/vcl/source/font/fontcharmap.cxx
@@ -20,6 +20,7 @@
#include <impfontcharmap.hxx>
#include <sal/log.hxx>
+#include <algorithm>
#include <vector>
#include <set>
@@ -149,6 +150,10 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
continue;
int nTmpOffset = GetUInt( p+4 );
+
+ if (nTmpOffset > nLength - 2 || nTmpOffset < 0)
+ continue;
+
int nTmpFormat = GetUShort( pCmap + nTmpOffset );
if( nTmpFormat == 12 ) // 32bit code -> glyph map format
nValue += 3;
@@ -178,12 +183,29 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
{
int nSegCountX2 = GetUShort( pCmap + nOffset + 6 );
nRangeCount = nSegCountX2/2 - 1;
- pCodePairs = new sal_UCS4[ nRangeCount * 2 ];
- pStartGlyphs = new int[ nRangeCount ];
+ if (nRangeCount < 0)
+ {
+ SAL_WARN("vcl.gdi", "negative RangeCount");
+ nRangeCount = 0;
+ }
+
const unsigned char* pLimitBase = pCmap + nOffset + 14;
const unsigned char* pBeginBase = pLimitBase + nSegCountX2 + 2;
const unsigned char* pDeltaBase = pBeginBase + nSegCountX2;
const unsigned char* pOffsetBase = pDeltaBase + nSegCountX2;
+
+ const int nOffsetBaseStart = pOffsetBase - pCmap;
+ const int nRemainingLen = nLength - nOffsetBaseStart;
+ const int nMaxPossibleRangeOffsets = nRemainingLen / 2;
+ if (nRangeCount > nMaxPossibleRangeOffsets)
+ {
+ SAL_WARN("vcl.gdi", "more range offsets requested then space available");
+ nRangeCount = std::max(0, nMaxPossibleRangeOffsets);
+ }
+
+ pCodePairs = new sal_UCS4[ nRangeCount * 2 ];
+ pStartGlyphs = new int[ nRangeCount ];
+
sal_UCS4* pCP = pCodePairs;
for( int i = 0; i < nRangeCount; ++i )
{
@@ -243,7 +265,7 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
if (nRangeCount > nMaxPossiblePairs)
{
SAL_WARN("vcl.gdi", "more code pairs requested then space available");
- nRangeCount = nMaxPossiblePairs;
+ nRangeCount = std::max(0, nMaxPossiblePairs);
}
pCodePairs = new sal_UCS4[ nRangeCount * 2 ];
@@ -317,7 +339,9 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
{
sal_UCS4 cMin = *(pCP++);
sal_UCS4 cEnd = *(pCP++);
- while( cMin < cEnd )
+ // ofz#25868 the conversion only makes sense with
+ // input codepoints in 0..SAL_MAX_UINT16 range
+ while (cMin < cEnd && cMin <= SAL_MAX_UINT16)
{
int j = 0;
for(; (cMin < cEnd) && (j < NINSIZE); ++cMin )