Skip to content

Commit

Permalink
Merged revision r6556 into the 2.1 branch via svnmerge from trunk
Browse files Browse the repository at this point in the history
........
  r6556 | muggenhor | 2009-01-24 19:15:19 +0100 (za, 24 jan 2009) | 5 lines
  
   * 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/branches/2.1@6557 4a71c877-e1ca-e34f-864e-861f7616d084
  • Loading branch information
Giel van Schijndel committed Jan 24, 2009
1 parent b478563 commit 33ed69a
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
4 changes: 4 additions & 0 deletions configure.ac
Expand Up @@ -36,6 +36,10 @@ AC_PROG_VERSION_CHECK([flex], [2.5.33], [2.5.34])
# 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])
Expand Down
18 changes: 18 additions & 0 deletions lib/framework/strlfuncs.h
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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. */
Expand Down
129 changes: 129 additions & 0 deletions m4/strlfuncs.m4
@@ -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])])
])
])

0 comments on commit 33ed69a

Please sign in to comment.