Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_ft2font.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ def test_ft2image_draw_rect_filled():
assert np.sum(a) == 255 * filled


def test_ft2image_dimension_overflow():
import ctypes
# Pick width == height such that width * height overflows the C `unsigned
# long` used to size the buffer (2**32 on LP64, 2**16 on a 32-bit long).
# Without the overflow guard, calloc would under-allocate and
# draw_rect_filled would write out of bounds.
n = 1 << (ctypes.sizeof(ctypes.c_ulong) * 8 // 2)
with pytest.warns(mpl.MatplotlibDeprecationWarning):
with pytest.raises((OverflowError, MemoryError)):
ft2font.FT2Image(n, n)


def test_ft2font_dejavu_attrs():
file = fm.findfont('DejaVu Sans')
font = ft2font.FT2Font(file)
Expand Down
14 changes: 13 additions & 1 deletion src/ft2font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#include <algorithm>
#include <cstdio>
#include <iterator>
#include <limits>
#include <map>
#include <new>
#include <set>
#include <stdexcept>
#include <string>
Expand All @@ -19,8 +21,18 @@
FT_Library _ft2Library;

FT2Image::FT2Image(unsigned long width, unsigned long height)
: m_buffer((unsigned char *)calloc(width * height, 1)), m_width(width), m_height(height)
: m_buffer(nullptr), m_width(width), m_height(height)
{
// Guard against width * height overflowing unsigned long, which would make
// calloc allocate a buffer far smaller than m_width * m_height and let
// draw_rect_filled write out of bounds.
if (width != 0 && height > std::numeric_limits<unsigned long>::max() / width) {
throw std::overflow_error("FT2Image dimensions are too large");
}
m_buffer = (unsigned char *)calloc(width * height, 1);
if (m_buffer == nullptr && width != 0 && height != 0) {
throw std::bad_alloc();
}
}

FT2Image::~FT2Image()
Expand Down