Fix #252: gd_error() garbles variable arguments

Currently gd_error() forwards to gd_error_ex(). However, both functions
accept a variable number of arguments, and simply forwarding the va_list
isn't portable, see <http://c-faq.com/varargs/handoff.html>. This article
also describes the usual workaround, namely to let the second function
accept a va_list instead of variable number of arguments.

We do so by introducing a static helper, what does not affect API/ABI
compatibility.
master
Christoph M. Becker 2016-07-17 14:03:20 +02:00
parent bbb5939f65
commit 9fd6021e12
7 changed files with 46 additions and 4 deletions

View File

@ -96,12 +96,19 @@ void gd_stderr_error(int priority, const char *format, va_list args)
static gdErrorMethod gd_error_method = gd_stderr_error;
static void _gd_error_ex(int priority, const char *format, va_list args)
{
if (gd_error_method) {
gd_error_method(priority, format, args);
}
}
void gd_error(const char *format, ...)
{
va_list args;
va_start(args, format);
gd_error_ex(GD_WARNING, format, args);
_gd_error_ex(GD_WARNING, format, args);
va_end(args);
}
void gd_error_ex(int priority, const char *format, ...)
@ -109,9 +116,7 @@ void gd_error_ex(int priority, const char *format, ...)
va_list args;
va_start(args, format);
if (gd_error_method) {
gd_error_method(priority, format, args);
}
_gd_error_ex(priority, format, args);
va_end(args);
}

View File

@ -21,6 +21,7 @@ if (BUILD_TEST)
bmp
freetype
gd
gd_error
gd2
gdimagearc
gdimagecolorclosest

View File

@ -15,6 +15,7 @@ TESTS =
include bmp/Makemodule.am
include freetype/Makemodule.am
include gd/Makemodule.am
include gd_error/Makemodule.am
include gd2/Makemodule.am
include gdimagearc/Makemodule.am
include gdimagecolorclosest/Makemodule.am

1
tests/gd_error/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/bug00252

View File

@ -0,0 +1,5 @@
LIST(APPEND TESTS_FILES
bug00252
)
ADD_GD_TESTS()

View File

@ -0,0 +1,5 @@
libgd_test_programs += \
gd_error/bug00252
EXTRA_DIST += \
gd_error/CMakeLists.txt

24
tests/gd_error/bug00252.c Normal file
View File

@ -0,0 +1,24 @@
/* See <https://github.com/libgd/libgd/issues/252>. */
#include "gd.h"
#include "gd_errors.h"
#include "gdtest.h"
void my_error_handler(int priority, const char *format, va_list args)
{
int n;
/* The following works according to
<https://www.gnu.org/software/libc/manual/html_node/Receiving-Arguments.html>.
It might not be portable, though. */
n = va_arg(args, int);
gdTestAssert(n == 42);
}
int main()
{
gdSetErrorMethod(my_error_handler);
gd_error_ex(GD_WARNING, "The answer is %i\n", 42);
gd_error("The answer is %i\n", 42);
return gdNumFailures();
}