File CVE-2022-38784.patch of Package poppler.27868
Index: poppler-0.62.0/poppler/JBIG2Stream.cc
===================================================================
--- poppler-0.62.0.orig/poppler/JBIG2Stream.cc 2017-12-03 19:25:06.000000000 +0000
+++ poppler-0.62.0/poppler/JBIG2Stream.cc 2022-12-02 18:16:59.711894336 +0000
@@ -2079,7 +2079,11 @@ void JBIG2Stream::readTextRegionSeg(Guin
for (i = 0; i < nRefSegs; ++i) {
if ((seg = findSegment(refSegs[i]))) {
if (seg->getType() == jbig2SegSymbolDict) {
- numSyms += ((JBIG2SymbolDict *)seg)->getSize();
+ const unsigned int segSize = ((JBIG2SymbolDict *)seg)->getSize();
+ if (unlikely(checkedAdd(numSyms, segSize, &numSyms))) {
+ error(errSyntaxError, getPos(), "Too many symbols in JBIG2 text region");
+ return;
+ }
} else if (seg->getType() == jbig2SegCodeTable) {
codeTables->append(seg);
}
Index: poppler-0.62.0/goo/gmem.h
===================================================================
--- poppler-0.62.0.orig/goo/gmem.h 2017-12-03 19:25:06.000000000 +0000
+++ poppler-0.62.0/goo/gmem.h 2022-12-02 18:11:32.687083038 +0000
@@ -28,6 +28,8 @@
#include <stdio.h>
#include "poppler-config.h"
+#include "GooCheckedOps.h"
+
#ifdef __cplusplus
extern "C" {
#endif
Index: poppler-0.62.0/goo/GooCheckedOps.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ poppler-0.62.0/goo/GooCheckedOps.h 2022-12-02 18:07:03.698640721 +0000
@@ -0,0 +1,65 @@
+//========================================================================
+//
+// GooCheckedOps.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
+// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
+// Copyright (C) 2019 Albert Astals Cid <aacid@kde.org>
+//
+//========================================================================
+
+#ifndef GOO_CHECKED_OPS_H
+#define GOO_CHECKED_OPS_H
+
+#include <limits>
+#include <type_traits>
+
+template<typename T> inline bool checkedAssign(long long lz, T *z) {
+ static_assert((std::numeric_limits<long long>::max)() > (std::numeric_limits<T>::max)(),
+ "The max of long long type must be larger to perform overflow checks.");
+ static_assert((std::numeric_limits<long long>::min)() < (std::numeric_limits<T>::min)(),
+ "The min of long long type must be smaller to perform overflow checks.");
+
+ if (lz > (std::numeric_limits<T>::max)() ||
+ lz < (std::numeric_limits<T>::min)()) {
+ return true;
+ }
+
+ *z = static_cast<T>(lz);
+ return false;
+}
+
+#ifndef __has_builtin
+ #define __has_builtin(x) 0
+#endif
+
+template<typename T> inline bool checkedAdd(T x, T y, T *z) {
+#if __GNUC__ >= 5 || __has_builtin(__builtin_add_overflow)
+ return __builtin_add_overflow(x, y, z);
+#else
+ const auto lz = static_cast<long long>(x) + static_cast<long long>(y);
+ return checkedAssign(lz, z);
+#endif
+}
+
+template<typename T> inline bool checkedMultiply(T x, T y, T *z) {
+#if __GNUC__ >= 5 || __has_builtin(__builtin_mul_overflow)
+ return __builtin_mul_overflow(x, y, z);
+#else
+ const auto lz = static_cast<long long>(x) * static_cast<long long>(y);
+ return checkedAssign(lz, z);
+#endif
+}
+
+template<typename T> inline T safeAverage(T a, T b) {
+ static_assert((std::numeric_limits<long long>::max)() > (std::numeric_limits<T>::max)(),
+ "The max of long long type must be larger to perform overflow checks.");
+ static_assert((std::numeric_limits<long long>::min)() < (std::numeric_limits<T>::min)(),
+ "The min of long long type must be smaller to perform overflow checks.");
+
+ return static_cast<T>((static_cast<long long>(a) + static_cast<long long>(b)) / 2);
+}
+
+#endif // GOO_CHECKED_OPS_H