URL: http://bugs.freeciv.org/Ticket/Display.html?id=36496
Besides potential crashes like the one reported in PR#36441 there's the
problem that libutf8's vsnprintf() function doesn't work on Windows
Vista, as was reported on the forums a while ago:
http://forum.freeciv.org/viewtopic.php?t=2642
While searching for the cause of the crash of PR#36441 I noticed the
vsnprintf() replacement code in support.c for platforms where a native
vsnprintf() does not exist or is broken. I tried to activate it by
undefining HAVE_VSNPRINTF and HAVE_WORKING_VSNPRINTF in config.h and
compiled without using libutf8 and it seems to work fine even with
reordered arguments (PR#12932). Then I wrote a little test:
char buf1[100], buf2[100], buf3[100];
printf(printf: %2$s %1$s\n, arg1, arg2);
sprintf(buf1, sprintf: %2$s %1$s\n, arg1, arg2);
snprintf(buf2, 100, snprintf: %2$s %1$s\n, arg1, arg2);
my_snprintf(buf3, 100, my_snprintf: %2$s %1$s\n, arg1, arg2);
printf(%s%s%s, buf1, buf2, buf3);
which resulted in:
printf: arg2 arg1
sprintf: arg2 arg1
snprintf: $s $s
my_snprintf: arg2 arg1
So it turns out that only the native snprintf() and vsnprintf()
functions are broken on Windows. My suggestion is now to replace any
remaining calls to snprintf() in S2_0 and S2_1 by calls to my_snprintf()
or cat_snprintf() and to skip the vsnprintf() tests in the configure
script on Windows, so the replacement code is being used. Then we
wouldn't need to use libutf8 anymore. Patches are attached.
Index: configure.ac
===
--- configure.ac (revision 12680)
+++ configure.ac (working copy)
@@ -356,18 +356,6 @@
AC_DEFINE_UNQUOTED(LOCALEDIR, ./share/locale, [Locale directory (windows)])
fi
-dnl Check libUTF8
-AC_ARG_WITH(libutf8,
-AC_HELP_STRING([--with-libutf8],
- [Use the libutf8 library (needed for some systems)]),
-[with_libutf8=$withval], [with_libutf8=no])
-if test $MINGW32 = yes || test $with_libutf8 = yes; then
- AC_CHECK_HEADER(libutf8.h, [],
- AC_MSG_ERROR([Could not find libutf8 library (libutf8.h)]))
- AC_DEFINE(HAVE_LIBUTF8_H, 1, [Use libutf8's stdio functions])
- LIBS=$LIBS -lutf8
-fi
-
dnl Check for zlib (needed for libpng)
AC_CHECK_LIB(z, gzgets, ,
AC_MSG_ERROR([Could not find zlib library.]), )
@@ -553,11 +541,16 @@
AC_FUNC_FORK
AC_FUNC_STRCOLL
AC_FUNC_VPRINTF
+
+dnl Windows vsnprintf doesn't support argument reordering (see PR#12932)
+if test x$MINGW32 != xyes; then
AC_FUNC_VSNPRINTF
+AC_CHECK_FUNCS([vsnprintf])
+fi
AC_CHECK_FUNCS([fileno ftime gethostname getpwuid inet_aton \
select snooze strerror strcasecmp strncasecmp \
- strlcat strlcpy strstr usleep vsnprintf uname flock \
+ strlcat strlcpy strstr usleep uname flock \
gethostbyname connect bind])
AC_MSG_CHECKING(for working gettimeofday)
Index: utility/support.h
===
--- utility/support.h (revision 12680)
+++ utility/support.h (working copy)
@@ -26,9 +26,6 @@
#ifdef HAVE_SYS_TYPES_H
#include sys/types.h
#endif
-#ifdef HAVE_LIBUTF8_H
-#include libutf8.h
-#endif
#ifdef TRUE
#undef TRUE
Index: server/savegame.c
===
--- server/savegame.c (revision 12680)
+++ server/savegame.c (working copy)
@@ -1055,7 +1055,7 @@
if (ptile-owner == NULL) {
strcpy(token, -);
} else {
- snprintf(token, sizeof(token), %d, ptile-owner-player_no);
+ my_snprintf(token, sizeof(token), %d, ptile-owner-player_no);
}
strcat(line, token);
if (x + 1 map.xsize) {
@@ -1075,7 +1075,7 @@
if (ptile-owner_source == NULL) {
strcpy(token, -);
} else {
- snprintf(token, sizeof(token), %d, ptile-owner_source-index);
+ my_snprintf(token, sizeof(token), %d, ptile-owner_source-index);
}
strcat(line, token);
if (x + 1 map.xsize) {
Index: utility/support.h
===
--- utility/support.h (revision 12680)
+++ utility/support.h (working copy)
@@ -26,9 +26,6 @@
#ifdef HAVE_SYS_TYPES_H
#include sys/types.h
#endif
-#ifdef HAVE_LIBUTF8_H
-#include libutf8.h
-#endif
#ifdef TRUE
#undef TRUE
Index: configure.ac
===
--- configure.ac (revision 12680)
+++ configure.ac (working copy)
@@ -355,18 +356,6 @@
AC_DEFINE_UNQUOTED(LOCALEDIR, ./share/locale, [Locale directory (windows)])
fi
-dnl Check libUTF8
-AC_ARG_WITH(libutf8,
-AC_HELP_STRING([--with-libutf8],
- [Use the libutf8 library (needed for some systems)]),
-[with_libutf8=$withval], [with_libutf8=no])
-if test $MINGW32 = yes || test $with_libutf8 = yes; then
- AC_CHECK_HEADER(libutf8.h, [],
- AC_MSG_ERROR([Could not find libutf8 library (libutf8.h)]))
-