From 963d12f9a31e56cad5d6c68f4d526925887cb28e Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 15 Jul 2020 09:50:52 +0200 Subject: fix gdImageStringFT() fails for empty strings https://github.com/libgd/libgd/issues/615 --- gd-bug615.patch | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gd.spec | 12 +++- 2 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 gd-bug615.patch diff --git a/gd-bug615.patch b/gd-bug615.patch new file mode 100644 index 0000000..74192e8 --- /dev/null +++ b/gd-bug615.patch @@ -0,0 +1,188 @@ +From 3dd0e308cbd2c24fde2fc9e9b707181252a2de95 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Tue, 5 May 2020 12:02:45 +0200 +Subject: [PATCH] Fix #615: gdImageStringFT() fails for empty strings as of + libgd 2.3.0 (#633) + +We change the return type of `textLayout()` to `ssize_t`, and signal +failure by returning `-1`, so that laying out an empty string is no +longer handled as failure. We make sure that no overflow occurs, +assuming that all `int` values can be fully represented as `ssize_t`. +--- + src/gdft.c | 18 +++++++++--------- + tests/gdimagestringft/.gitignore | 1 + + tests/gdimagestringft/CMakeLists.txt | 1 + + tests/gdimagestringft/Makemodule.am | 1 + + tests/gdimagestringft/bug00615.c | 25 +++++++++++++++++++++++++ + 5 files changed, 37 insertions(+), 9 deletions(-) + create mode 100644 tests/gdimagestringft/bug00615.c + +diff --git a/src/gdft.c b/src/gdft.c +index b483b383..186eefff 100644 +--- a/src/gdft.c ++++ b/src/gdft.c +@@ -441,7 +441,7 @@ typedef struct { + uint32_t cluster; + } glyphInfo; + +-static size_t ++static ssize_t + textLayout(uint32_t *text, int len, + FT_Face face, gdFTStringExtraPtr strex, + glyphInfo **glyph_info) +@@ -459,19 +459,19 @@ textLayout(uint32_t *text, int len, + !raqm_set_par_direction (rq, RAQM_DIRECTION_DEFAULT) || + !raqm_layout (rq)) { + raqm_destroy (rq); +- return 0; ++ return -1; + } + + glyphs = raqm_get_glyphs (rq, &count); + if (!glyphs) { + raqm_destroy (rq); +- return 0; ++ return -1; + } + + info = (glyphInfo*) gdMalloc (sizeof (glyphInfo) * count); + if (!info) { + raqm_destroy (rq); +- return 0; ++ return -1; + } + + for (i = 0; i < count; i++) { +@@ -489,7 +489,7 @@ textLayout(uint32_t *text, int len, + FT_Error err; + info = (glyphInfo*) gdMalloc (sizeof (glyphInfo) * len); + if (!info) { +- return 0; ++ return -1; + } + for (count = 0; count < len; count++) { + /* Convert character code to glyph index */ +@@ -508,7 +508,7 @@ textLayout(uint32_t *text, int len, + err = FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT); + if (err) { + gdFree (info); +- return 0; ++ return -1; + } + info[count].index = glyph_index; + info[count].x_offset = 0; +@@ -527,7 +527,7 @@ textLayout(uint32_t *text, int len, + #endif + + *glyph_info = info; +- return count; ++ return count <= SSIZE_MAX ? count : -1; + } + + /********************************************************************/ +@@ -1108,7 +1108,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, const c + char *tmpstr = 0; + uint32_t *text; + glyphInfo *info = NULL; +- size_t count; ++ ssize_t count; + int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); + FT_BitmapGlyph bm; + /* 2.0.13: Bob Ostermann: don't force autohint, that's just for testing +@@ -1409,7 +1409,7 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, const c + + count = textLayout (text , i, face, strex, &info); + +- if (!count) { ++ if (count < 0) { + gdFree (text); + gdFree (tmpstr); + gdCacheDelete (tc_cache); +diff --git a/tests/gdimagestringft/CMakeLists.txt b/tests/gdimagestringft/CMakeLists.txt +index f46b9006..42868a27 100644 +--- a/tests/gdimagestringft/CMakeLists.txt ++++ b/tests/gdimagestringft/CMakeLists.txt +@@ -1,5 +1,6 @@ + IF(FREETYPE_FOUND) + LIST(APPEND TESTS_FILES ++ bug00615 + gdimagestringft_bbox + ) + ENDIF(FREETYPE_FOUND) +diff --git a/tests/gdimagestringft/Makemodule.am b/tests/gdimagestringft/Makemodule.am +index 0dfe26fb..a62081f4 100644 +--- a/tests/gdimagestringft/Makemodule.am ++++ b/tests/gdimagestringft/Makemodule.am +@@ -1,5 +1,6 @@ + if HAVE_LIBFREETYPE + libgd_test_programs += \ ++ gdimagestringft/bug00615 \ + gdimagestringft/gdimagestringft_bbox + endif + +diff --git a/tests/gdimagestringft/bug00615.c b/tests/gdimagestringft/bug00615.c +new file mode 100644 +index 00000000..0da51dae +--- /dev/null ++++ b/tests/gdimagestringft/bug00615.c +@@ -0,0 +1,25 @@ ++/** ++ * Test that rendering an empty string does not fail ++ * ++ * Rendering an empty string with gdImageStringFT() is not supposed to fail; ++ * it is just a no-op. ++ * ++ * See ++ */ ++ ++#include "gd.h" ++#include "gdtest.h" ++ ++int main() ++{ ++ gdImagePtr im = gdImageCreate(100, 100); ++ ++ int rect[8]; ++ int fg = gdImageColorAllocate(im, 255, 255, 255); ++ char *path = gdTestFilePath("freetype/DejaVuSans.ttf"); ++ char *res = gdImageStringFT(im, rect, fg, path, 12, 0, 10, 10, ""); ++ ++ gdTestAssert(res == NULL); ++ ++ return gdNumFailures(); ++} +From 0be6aec0fe11dce8b8a5674eea5ee23bc700042e Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Wed, 15 Jul 2020 08:56:08 +0200 +Subject: [PATCH] Fix #615 using libraqm and avoid unneeded free + +--- + src/gdft.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/gdft.c b/src/gdft.c +index 186eefff..7eb97077 100644 +--- a/src/gdft.c ++++ b/src/gdft.c +@@ -449,6 +449,10 @@ textLayout(uint32_t *text, int len, + size_t count; + glyphInfo *info; + ++ if (!len) { ++ return 0; ++ } ++ + #ifdef HAVE_LIBRAQM + size_t i; + raqm_glyph_t *glyphs; +@@ -1566,7 +1570,9 @@ BGD_DECLARE(char *) gdImageStringFTEx (gdImage * im, int *brect, int fg, const c + } + + gdFree(text); +- gdFree(info); ++ if (info) { ++ gdFree(info); ++ } + + /* Save the (unkerned) advance from the last character in the xshow vector */ + if (strex && (strex->flags & gdFTEX_XSHOW) && strex->xshow) { diff --git a/gd.spec b/gd.spec index 9ab9c57..fc66ff4 100644 --- a/gd.spec +++ b/gd.spec @@ -37,7 +37,7 @@ Name: gd Name: gd-last %endif Version: 2.3.0 -Release: 1%{?prever}%{?short}%{?dist} +Release: 2%{?prever}%{?short}%{?dist} License: MIT URL: http://libgd.github.io/ %if 0%{?commit:1} @@ -50,6 +50,8 @@ Source0: https://github.com/libgd/libgd/releases/download/gd-%{version}/li # Missing, temporary workaround, fixed upstream for next version Source1: https://raw.githubusercontent.com/libgd/libgd/gd-%{version}/config/getlib.sh +Patch0: gd-bug615.patch + BuildRequires: freetype-devel BuildRequires: fontconfig-devel BuildRequires: gettext-devel @@ -76,6 +78,7 @@ BuildRequires: pkgconfig BuildRequires: libtool BuildRequires: perl BuildRequires: perl-generators +BuildRequires: perl(FindBin) # for fontconfig/basic test BuildRequires: liberation-sans-fonts %if 0%{?fedora} >= 29 @@ -147,6 +150,7 @@ files for gd, a graphics library for creating PNG and JPEG graphics. %prep %setup -q -n libgd-%{version}%{?prever:-%{prever}} +%patch0 -p1 install -m 0755 %{SOURCE1} config/ : $(perl config/getver.pl) @@ -218,7 +222,7 @@ XFAIL_TESTS="freetype/bug00132 $XFAIL_TESTS" export XFAIL_TESTS : Upstream test suite -make check +make check %{?_smp_mflags} : Check content of pkgconfig grep %{version} $RPM_BUILD_ROOT%{_libdir}/pkgconfig/gdlib.pc @@ -245,6 +249,10 @@ grep %{version} $RPM_BUILD_ROOT%{_libdir}/pkgconfig/gdlib.pc %changelog +* Wed Jul 15 2020 Remi Collet - 2.3.0-2 +- fix gdImageStringFT() fails for empty strings + https://github.com/libgd/libgd/issues/615 + * Tue Mar 24 2020 Remi Collet - 2.3.0-1 - update to 2.3.0 - add dependency on libraqm -- cgit