Added ImageFont.MAX_STRING_LENGTH

This commit is contained in:
Andrew Murray 2023-06-30 23:32:26 +10:00
parent 7c945f5131
commit 1fe1bb49c4
4 changed files with 64 additions and 0 deletions

View File

@ -1038,6 +1038,25 @@ def test_render_mono_size():
assert_image_equal_tofile(im, "Tests/images/text_mono.gif")
def test_too_many_characters(font):
with pytest.raises(ValueError):
font.getlength("A" * 1000001)
with pytest.raises(ValueError):
font.getbbox("A" * 1000001)
with pytest.raises(ValueError):
font.getmask2("A" * 1000001)
transposed_font = ImageFont.TransposedFont(font)
with pytest.raises(ValueError):
transposed_font.getlength("A" * 1000001)
default_font = ImageFont.load_default()
with pytest.raises(ValueError):
default_font.getlength("A" * 1000001)
with pytest.raises(ValueError):
default_font.getbbox("A" * 1000001)
@pytest.mark.parametrize(
"test_file",
[

View File

@ -18,6 +18,15 @@ OpenType fonts (as well as other font formats supported by the FreeType
library). For earlier versions, TrueType support is only available as part of
the imToolkit package.
.. warning::
To protect against potential DOS attacks when using arbitrary strings as
text input, Pillow will raise a ``ValueError`` if the number of characters
is over a certain limit, :py:data:`MAX_STRING_LENGTH`.
This threshold can be changed by setting
:py:data:`MAX_STRING_LENGTH`. It can be disabled by setting
``ImageFont.MAX_STRING_LENGTH = None``.
Example
-------
@ -73,3 +82,12 @@ Constants
Requires Raqm, you can check support using
:py:func:`PIL.features.check_feature` with ``feature="raqm"``.
Constants
---------
.. data:: MAX_STRING_LENGTH
Set to 1,000,000, to protect against potential DOS attacks. Pillow will
raise a ``ValueError`` if the number of characters is over this limit. The
check can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.

View File

@ -170,6 +170,18 @@ now been fixed.
This effectively dates to the PIL fork, since problem images would still have
been processed before Pillow started checking for decompression bombs.
Added ImageFont.MAX_STRING_LENGTH
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To protect against potential DOS attacks when using arbitrary strings as text
input, Pillow will now raise a ``ValueError`` if the number of characters
passed into ImageFont methods is over a certain limit,
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.
This threshold can be changed by setting
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It can be disabled by setting
``ImageFont.MAX_STRING_LENGTH = None``.
Other Changes
=============

View File

@ -41,6 +41,9 @@ class Layout(IntEnum):
RAQM = 1
MAX_STRING_LENGTH = 1000000
try:
from . import _imagingft as core
except ImportError as ex:
@ -49,6 +52,12 @@ except ImportError as ex:
core = DeferredError(ex)
def _string_length_check(text):
if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
msg = "too many characters in string"
raise ValueError(msg)
# FIXME: add support for pilfont2 format (see FontFile.py)
# --------------------------------------------------------------------
@ -152,6 +161,7 @@ class ImageFont:
:return: ``(left, top, right, bottom)`` bounding box
"""
_string_length_check(text)
width, height = self.font.getsize(text)
return 0, 0, width, height
@ -162,6 +172,7 @@ class ImageFont:
.. versionadded:: 9.2.0
"""
_string_length_check(text)
width, height = self.font.getsize(text)
return width
@ -309,6 +320,7 @@ class FreeTypeFont:
:return: Width for horizontal, height for vertical text.
"""
_string_length_check(text)
return self.font.getlength(text, mode, direction, features, language) / 64
def getbbox(
@ -368,6 +380,7 @@ class FreeTypeFont:
:return: ``(left, top, right, bottom)`` bounding box
"""
_string_length_check(text)
size, offset = self.font.getsize(
text, mode, direction, features, language, anchor
)
@ -546,6 +559,7 @@ class FreeTypeFont:
:py:mod:`PIL.Image.core` interface module, and the text offset, the
gap between the starting coordinate and the first marking
"""
_string_length_check(text)
if start is None:
start = (0, 0)
im, size, offset = self.font.render(
@ -684,6 +698,7 @@ class TransposedFont:
if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
msg = "text length is undefined for text rotated by 90 or 270 degrees"
raise ValueError(msg)
_string_length_check(text)
return self.font.getlength(text, *args, **kwargs)