From 073913a2cc102f14aa54eaf9d1ecfa3bd44656fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Fri, 15 May 2026 09:16:02 +0100 Subject: [PATCH] ofz#513277199 Integer-overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Caolán McNamara Change-Id: I8a07f47f382502ab24670a270e8cd23a888f1ba4 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2656 Reviewed-by: Michael Stahl Tested-by: Jenkins CPCI (cherry picked from commit 6eb214dbe24ac7c1cde3fe8a6ce242f2d7e24151) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207713 Reviewed-by: Xisco Fauli Tested-by: Xisco Fauli --- vcl/source/fontsubset/cff.cxx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx index fb1409fcacac..bbcb5176dbf8 100644 --- a/vcl/source/fontsubset/cff.cxx +++ b/vcl/source/fontsubset/cff.cxx @@ -1343,6 +1343,11 @@ private: bool callType2Subr(bool bGlobal, int nSubrNumber); sal_Int32 getReadOfs() const { return static_cast(mpReadPtr - mpBasePtr); } + // Abandon the current dict-data parse on malformed input. Advancing + // mpReadPtr past mpReadEnd exits the parse loop, and trips the mpReadPtr + // != mpReadEnd post-check so flags as a parse failure. + void abandonDictParse() { mpReadPtr = mpReadEnd + 1; } + const U8* mpBasePtr; const U8* mpBaseEnd; @@ -2453,6 +2458,8 @@ RealType CffContext::readRealVal() int nExpSign = 0; S64 nNumber = 0; RealType fReal = +1.0; + // nNumber * 10 + 9 must fit in S64; anything beyond is a malformed + constexpr S64 nDigitCap = (SAL_MAX_INT64 - 9) / 10; for (;;) { const U8 c = *(mpReadPtr++); // read nibbles @@ -2460,6 +2467,12 @@ RealType CffContext::readRealVal() const U8 nH = c >> 4U; if (nH <= 9) { + if (nNumber > nDigitCap) + { + SAL_WARN("vcl.fonts.cff", "CFF real number overflow"); + abandonDictParse(); + return 0.0; + } nNumber = nNumber * 10 + nH; --nExpVal; } @@ -2492,6 +2505,12 @@ RealType CffContext::readRealVal() const U8 nL = c & 0x0F; if (nL <= 9) { + if (nNumber > nDigitCap) + { + SAL_WARN("vcl.fonts.cff", "CFF real number overflow"); + abandonDictParse(); + return 0.0; + } nNumber = nNumber * 10 + nL; --nExpVal; }