c6d8c5
From ca6bb16f2d10dfc918ddc857118ed3ba7e5db90d Mon Sep 17 00:00:00 2001
c6d8c5
From: Lumir Balhar <lbalhar@redhat.com>
c6d8c5
Date: Mon, 13 Nov 2023 12:30:56 +0100
c6d8c5
Subject: [PATCH] CVE-2023-44271
c6d8c5
c6d8c5
---
c6d8c5
 PIL/ImageFont.py | 21 ++++++++++++++++++---
c6d8c5
 1 file changed, 18 insertions(+), 3 deletions(-)
c6d8c5
c6d8c5
diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py
c6d8c5
index 8ec60fe..4503df4 100644
c6d8c5
--- a/PIL/ImageFont.py
c6d8c5
+++ b/PIL/ImageFont.py
c6d8c5
@@ -35,11 +35,20 @@ class _imagingft_not_installed:
c6d8c5
     def __getattr__(self, id):
c6d8c5
         raise ImportError("The _imagingft C module is not installed")
c6d8c5
 
c6d8c5
+MAX_STRING_LENGTH = 1000000
c6d8c5
+
c6d8c5
 try:
c6d8c5
     import _imagingft as core
c6d8c5
 except ImportError:
c6d8c5
     core = _imagingft_not_installed()
c6d8c5
 
c6d8c5
+
c6d8c5
+def _string_length_check(text):
c6d8c5
+    if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
c6d8c5
+        msg = "too many characters in string"
c6d8c5
+        raise ValueError(msg)
c6d8c5
+
c6d8c5
+
c6d8c5
 # FIXME: add support for pilfont2 format (see FontFile.py)
c6d8c5
 
c6d8c5
 # --------------------------------------------------------------------
c6d8c5
@@ -118,9 +127,12 @@ class ImageFont:
c6d8c5
 
c6d8c5
         self.font = Image.core.font(image.im, data)
c6d8c5
 
c6d8c5
-        # delegate critical operations to internal type
c6d8c5
-        self.getsize = self.font.getsize
c6d8c5
-        self.getmask = self.font.getmask
c6d8c5
+    def getsize(self, text):
c6d8c5
+        _string_length_check(text)
c6d8c5
+        return self.font.getsize(text)
c6d8c5
+    
c6d8c5
+    def getmask(self, text, mode=""):
c6d8c5
+        return self.font.getmask(text, mode)
c6d8c5
 
c6d8c5
 ##
c6d8c5
 # Wrapper for FreeType fonts.  Application code should use the
c6d8c5
@@ -140,12 +152,14 @@ class FreeTypeFont:
c6d8c5
         return self.font.ascent, self.font.descent
c6d8c5
 
c6d8c5
     def getsize(self, text):
c6d8c5
+        _string_length_check(text)
c6d8c5
         return self.font.getsize(text)[0]
c6d8c5
 
c6d8c5
     def getmask(self, text, mode=""):
c6d8c5
         return self.getmask2(text, mode)[0]
c6d8c5
 
c6d8c5
     def getmask2(self, text, mode="", fill=Image.core.fill):
c6d8c5
+        _string_length_check(text)
c6d8c5
         size, offset = self.font.getsize(text)
c6d8c5
         im = fill("L", size, 0)
c6d8c5
         self.font.render(text, im.id, mode=="1")
c6d8c5
@@ -168,6 +182,7 @@ class TransposedFont:
c6d8c5
         self.orientation = orientation # any 'transpose' argument, or None
c6d8c5
 
c6d8c5
     def getsize(self, text):
c6d8c5
+        _string_length_check(text)
c6d8c5
         w, h = self.font.getsize(text)
c6d8c5
         if self.orientation in (Image.ROTATE_90, Image.ROTATE_270):
c6d8c5
             return h, w
c6d8c5
-- 
c6d8c5
2.41.0
c6d8c5