* Check whether the system itself already provides strlcpy and/or strlcat
- If it does, check whether it's behaviour is consistent with our implementation - If behaviour is consistent: use the system's implementation - If not, rename our implementation (to prevent symbol clashes) and use our own git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@6556 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
1f4e369cf2
commit
cb22e77099
|
@ -43,6 +43,10 @@ AM_CONDITIONAL([PERL_AVAILABLE], test -n "$PERL")
|
|||
# Enable Compiler/LibC GNU extensions
|
||||
AC_GNU_SOURCE
|
||||
|
||||
# Check for the strlcpy and strlcat functions
|
||||
AX_CHECK_STRLCPY
|
||||
AX_CHECK_STRLCAT
|
||||
|
||||
# Check for gettext
|
||||
AM_GNU_GETTEXT([external])
|
||||
AC_PROG_VERSION_CHECK([msgfmt xgettext], [0.15])
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef HAVE_VALID_STRLCPY
|
||||
# ifdef HAVE_SYSTEM_STRLCPY
|
||||
// If the system provides a non-conformant strlcpy we use our own
|
||||
# ifdef strlcpy
|
||||
# undef strlcpy
|
||||
# endif
|
||||
# define strlcpy wz_strlcpy
|
||||
# endif // HAVE_SYSTEM_STRLCPY
|
||||
/**
|
||||
* A safer variant of \c strncpy and its completely unsafe variant \c strcpy.
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
|
@ -61,7 +69,16 @@ static inline size_t strlcpy(char *WZ_DECL_RESTRICT dst, const char *WZ_DECL_RES
|
|||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
#endif // HAVE_VALID_STRLCPY
|
||||
|
||||
#ifndef HAVE_VALID_STRLCAT
|
||||
# ifdef HAVE_SYSTEM_STRLCAT
|
||||
// If the system provides a non-conformant strlcat we use our own
|
||||
# ifdef strlcat
|
||||
# undef strlcat
|
||||
# endif
|
||||
# define strlcat wz_strlcat
|
||||
# endif // HAVE_SYSTEM_STRLCAT
|
||||
/**
|
||||
* A safer variant of \c strncat and its completely unsafe variant \c strcat.
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
|
@ -105,6 +122,7 @@ static inline size_t strlcat(char *WZ_DECL_RESTRICT dst, const char *WZ_DECL_RES
|
|||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
#endif // HAVE_VALID_STRLCAT
|
||||
|
||||
/* Static array versions of common string functions. Safer because one less parameter to screw up.
|
||||
* Can only be used on strings longer than the length of a pointer, because we use this for debugging. */
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
# strlfuncs.m4
|
||||
dnl Copyright (C) 2009 Giel van Schijndel
|
||||
dnl Copyright (C) 2009 Warzone Resurrection Project
|
||||
dnl
|
||||
dnl This file is free software; I, Giel van Schijndel give unlimited permission
|
||||
dnl to copy and/or distribute it, with or without modifications, as long as
|
||||
dnl this notice is preserved.
|
||||
dnl
|
||||
dnl This file can be used in projects which are not available under the GNU
|
||||
dnl General Public License or the GNU Library General Public License. Please
|
||||
dnl note that the the rest of the Warzone 2100 package is covered by the GNU
|
||||
dnl General Public License.
|
||||
dnl It is not *not* in the public domain.
|
||||
|
||||
dnl Authors:
|
||||
dnl Giel van Schijndel <muggenhor@gna.org>, 2009
|
||||
|
||||
AC_PREREQ(2.56)
|
||||
|
||||
AC_DEFUN([AX_CHECK_STRLCPY],[
|
||||
AC_CHECK_FUNC([strlcpy],[
|
||||
AC_DEFINE([HAVE_SYSTEM_STRLCPY], [], [The system provides strlcpy])
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char srcstr1[] = "source string 1";
|
||||
static char buf1[sizeof(srcstr1)];
|
||||
static char buf2[sizeof(srcstr1) * 2];
|
||||
static char buf3[sizeof(srcstr1) / 2];
|
||||
]],[[
|
||||
static const char initial_value = 0x55;
|
||||
/* Make sure that all buffers are filled with an arbitrary non-NULL value, to
|
||||
* check that overflow doesn't occur.
|
||||
*/
|
||||
memset(buf1, initial_value, sizeof(buf1));
|
||||
memset(buf2, initial_value, sizeof(buf2));
|
||||
memset(buf3, initial_value, sizeof(buf3));
|
||||
|
||||
/* Check whether behaviour is consistent with strcpy/strncpy for strings where
|
||||
* the buffer size matches
|
||||
*/
|
||||
if (strlcpy(buf1, srcstr1, sizeof(buf1)) != strlen(srcstr1)
|
||||
|| memcmp(srcstr1, buf1, sizeof(buf1)) != 0)
|
||||
exit(EXIT_FAILURE);
|
||||
/* Check whether behaviour is consistent with strcpy/strncpy for strings where
|
||||
* the buffer size is larger than required
|
||||
*/
|
||||
if (strlcpy(buf2, srcstr1, sizeof(buf2)) != strlen(srcstr1)
|
||||
|| memcmp(srcstr1, buf2, sizeof(srcstr1)) != 0)
|
||||
exit(EXIT_FAILURE);
|
||||
/* Check whether strlcpy *always* returns the amount of characters in the
|
||||
* source string */
|
||||
if (strlcpy(buf3, srcstr1, 0) != strlen(srcstr1)
|
||||
|| buf3[0] != initial_value /* verify that no data has been written */
|
||||
|| strlcpy(buf3, srcstr1, sizeof(buf3)) != strlen(srcstr1)
|
||||
/* Check whether strlcpy fills the buffer properly with the first part of the
|
||||
* source string if the buffer is too small
|
||||
*/
|
||||
|| memcmp(srcstr1, buf3, sizeof(buf3) - 1) != 0
|
||||
/* Check whether strlcpy properly guarantees NUL-termination */
|
||||
|| buf3[sizeof(buf3) - 1] != '\0')
|
||||
exit(EXIT_FAILURE);
|
||||
]])
|
||||
],[AC_DEFINE([HAVE_VALID_STRLCPY], [], [The system provides a strlcpy we can use])])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_CHECK_STRLCAT],[
|
||||
AC_CHECK_FUNC([strlcat],[
|
||||
AC_DEFINE([HAVE_SYSTEM_STRLCAT], [], [The system provides strlcat])
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char srcstr1[] = "source string 1";
|
||||
static const char srcstr2[] = "concatenation string";
|
||||
static char buf1[sizeof(srcstr1) + sizeof(srcstr2)];
|
||||
static char buf2[(sizeof(srcstr1) + sizeof(srcstr2)) * 2];
|
||||
static char buf3[sizeof(srcstr1) / 2];
|
||||
static char buf4[(sizeof(srcstr1) + sizeof(srcstr2) / 2)];
|
||||
]],[[
|
||||
static const char initial_value = 0x55;
|
||||
/* Make sure that all buffers are filled with an arbitrary non-NULL value, to
|
||||
* check that overflow doesn't occur.
|
||||
*/
|
||||
memset(buf1, initial_value, sizeof(buf1));
|
||||
memset(buf2, initial_value, sizeof(buf2));
|
||||
memset(buf3, initial_value, sizeof(buf3));
|
||||
memset(buf4, initial_value, sizeof(buf4));
|
||||
|
||||
/* Prefill the buffers so that we can check concatenation */
|
||||
strncpy(buf1, srcstr1, sizeof(buf1));
|
||||
strncpy(buf2, srcstr1, sizeof(buf2));
|
||||
strncpy(buf3, srcstr1, sizeof(buf3));
|
||||
strncpy(buf4, srcstr1, sizeof(buf4));
|
||||
|
||||
/* Check whether behaviour is consistent with strcat/strncat for strings where
|
||||
* the buffer size matches
|
||||
*/
|
||||
if (strlcat(buf1, srcstr2, sizeof(buf1)) != (strlen(srcstr1) + strlen(srcstr2))
|
||||
|| memcmp(srcstr1, buf1, strlen(srcstr1)) != 0
|
||||
|| memcmp(srcstr2, buf1 + strlen(srcstr1), sizeof(srcstr2)) != 0)
|
||||
exit(EXIT_FAILURE);
|
||||
/* Check whether behaviour is consistent with strcat/strncat for strings where
|
||||
* the buffer size is larger than required
|
||||
*/
|
||||
if (strlcat(buf2, srcstr2, sizeof(buf2)) != (strlen(srcstr1) + strlen(srcstr2))
|
||||
|| memcmp(srcstr1, buf2, strlen(srcstr1)) != 0
|
||||
|| memcmp(srcstr2, buf2 + strlen(srcstr1), sizeof(srcstr2)) != 0)
|
||||
exit(EXIT_FAILURE);
|
||||
/* Check whether strlcat *always* returns the amount of characters the
|
||||
* resulting string would have if the destination buffer was large enough.
|
||||
*/
|
||||
if (strlcat(buf3, srcstr2, 0) != strlen(srcstr2)
|
||||
|| strlcat(buf3, srcstr2, sizeof(buf3)) != (sizeof(buf3) + strlen(srcstr2))
|
||||
/* Check whether strlcat fills the buffer properly with the first part of the
|
||||
* source string if the buffer is too small
|
||||
*/
|
||||
|| memcmp(srcstr1, buf3, sizeof(buf3) - 1) != 0)
|
||||
exit(EXIT_FAILURE);
|
||||
/* Check whether strlcat properly guarantees NUL-termination */
|
||||
if (strlcat(buf4, srcstr2, sizeof(buf4)) != (strlen(srcstr1) + strlen(srcstr2))
|
||||
|| buf4[sizeof(buf4) - 1] != '\0')
|
||||
exit(EXIT_FAILURE);
|
||||
]])
|
||||
],[AC_DEFINE([HAVE_VALID_STRLCAT], [], [The system provides a strlcat we can use])])
|
||||
])
|
||||
])
|
Loading…
Reference in New Issue