diff --git a/debian/changelog b/debian/changelog index e62e016..c5cf1fc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +opencc (1.1.9+ds1-1deepin1) unstable; urgency=medium + + * Fix CVE-2025-15536: heap buffer overflow in UTF-8 processing + + -- deepin-ci-robot Wed, 29 Apr 2026 19:47:21 +0800 + opencc (1.1.9+ds1-1deepin0) unstable; urgency=medium * No source change upload against GCC 12. diff --git a/debian/patches/0006-CVE-2025-15536.patch b/debian/patches/0006-CVE-2025-15536.patch new file mode 100644 index 0000000..4f8cc4d --- /dev/null +++ b/debian/patches/0006-CVE-2025-15536.patch @@ -0,0 +1,85 @@ +Description: Fix heap buffer overflow in UTF-8 processing + Two out-of-bounds read issues were identified in OpenCC's UTF-8 + processing logic when handling malformed or truncated UTF-8 sequences. + . + 1) MaxMatchSegmentation: + NextCharLength() could return a value larger than the remaining input size. + The previous logic subtracted this value from a size_t length counter, + potentially causing underflow and subsequent out-of-bounds reads. + . + 2) Conversion: + Similar length handling could allow reads past the end of the input buffer + during dictionary matching. + . + This patch fixes both issues by: + - Explicitly tracking the end of the input buffer + - Recomputing remaining length on each iteration + - Clamping matched character and key lengths to the remaining buffer size + - Preventing reads past the null terminator +Origin: upstream, https://github.com/BYVoid/OpenCC/commit/345c9a50ab07018f1b4439776bad78a0d40778ec +Bug: https://github.com/BYVoid/OpenCC/issues/997 +Bug-Debian: https://bugs.debian.org/1126286 +Forwarded: not-needed +Last-Update: 2026-04-29 + +--- opencc-1.1.9+ds1.orig/src/Conversion.cpp ++++ opencc-1.1.9+ds1/src/Conversion.cpp +@@ -25,14 +25,30 @@ using namespace opencc; + + std::string Conversion::Convert(const char* phrase) const { + std::ostringstream buffer; ++ // Calculate string end to prevent reading beyond null terminator ++ const char* phraseEnd = phrase; ++ while (*phraseEnd != '\0') { ++ phraseEnd++; ++ } ++ + for (const char* pstr = phrase; *pstr != '\0';) { +- Optional matched = dict->MatchPrefix(pstr); ++ size_t remainingLength = phraseEnd - pstr; ++ Optional matched = dict->MatchPrefix(pstr, remainingLength); + size_t matchedLength; + if (matched.IsNull()) { + matchedLength = UTF8Util::NextCharLength(pstr); ++ // Ensure we don't read beyond the null terminator ++ if (matchedLength > remainingLength) { ++ matchedLength = remainingLength; ++ } + buffer << UTF8Util::FromSubstr(pstr, matchedLength); + } else { + matchedLength = matched.Get()->KeyLength(); ++ // Defensive: ensure dictionary key length does not exceed remaining input ++ // (MatchPrefix should already guarantee this, but defense in depth) ++ if (matchedLength > remainingLength) { ++ matchedLength = remainingLength; ++ } + buffer << matched.Get()->GetDefault(); + } + pstr += matchedLength; +--- opencc-1.1.9+ds1.orig/src/MaxMatchSegmentation.cpp ++++ opencc-1.1.9+ds1/src/MaxMatchSegmentation.cpp +@@ -26,12 +26,16 @@ SegmentsPtr MaxMatchSegmentation::Segmen + }; + size_t length = text.length(); + for (const char* pstr = text.c_str(); *pstr != '\0';) { ++ // Recompute remaining length each iteration to avoid underflow ++ size_t remainingLength = text.c_str() + text.length() - pstr; + const Optional& matched = dict->MatchPrefix(pstr, length); + size_t matchedLength; + if (matched.IsNull()) { + matchedLength = UTF8Util::NextCharLength(pstr); ++ // Clamp matchedLength to remaining buffer size ++ if (matchedLength > remainingLength) matchedLength = remainingLength; + segLength += matchedLength; + } else { + clearBuffer(); + matchedLength = matched.Get()->KeyLength(); + segments->AddSegment(matched.Get()->Key()); + segStart = pstr + matchedLength; + } + pstr += matchedLength; +- length -= matchedLength; ++ // No need to track length, we recompute remainingLength each iteration + } + clearBuffer(); + return segments; diff --git a/debian/patches/series b/debian/patches/series index a577d9a..7cbecda 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -2,3 +2,4 @@ 0003-no-remote-images-when-reading-docs-on-disk.patch 0004-Use-system-googletest.patch 0005-Disable-build-in-setup.py.patch +0006-CVE-2025-15536.patch