fix gdImageStringFT() fails for empty strings

https://github.com/libgd/libgd/issues/615
This commit is contained in:
Remi Collet 2020-07-15 10:10:25 +02:00
parent 7479fbab78
commit e869ce049e
2 changed files with 195 additions and 1 deletions

188
gd-bug615.patch Normal file
View File

@ -0,0 +1,188 @@
From 3dd0e308cbd2c24fde2fc9e9b707181252a2de95 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
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 <https://github.com/libgd/libgd/issues/615>
+ */
+
+#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 <remi@remirepo.net>
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) {

View File

@ -5,7 +5,7 @@
Summary: A graphics library for quick creation of PNG or JPEG images
Name: gd
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}
@ -18,6 +18,7 @@ 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
@ -89,6 +90,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)
@ -167,6 +169,10 @@ grep %{version} $RPM_BUILD_ROOT%{_libdir}/pkgconfig/gdlib.pc
%changelog
* Wed Jul 15 2020 Remi Collet <remi@remirepo.net> - 2.3.0-2
- fix gdImageStringFT() fails for empty strings
https://github.com/libgd/libgd/issues/615
* Tue Mar 24 2020 Remi Collet <remi@remirepo.net> - 2.3.0-1
- update to 2.3.0
- add dependency on libraqm