// // aegis - a project change supervisor // Copyright (C) 1994, 1996, 1997, 2002, 2004-2008 Peter Miller // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 3 of // the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #ifndef COMMON_AC_STRING_H #define COMMON_AC_STRING_H #include #if STDC_HEADERS || HAVE_STRING_H # include // An ANSI string.h and pre-ANSI memory.h might conflict. # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif #else // memory.h and strings.h conflict on some systems. # include #endif extern "C" { #if !HAVE_STRCASECMP int strcasecmp(const char *, const char *); #endif #if !HAVE_STRNCASECMP int strncasecmp(const char *, const char *, size_t); #endif #if !HAVE_DECL_STRSIGNAL const char *strsignal(int); #endif #if !HAVE_STRVERSCMP int strverscmp(const char *, const char *); #endif #if !HAVE_STRLCPY size_t strlcpy(char *dst, const char *src, size_t size); #endif #if !HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t size); #endif #if !HAVE_STRENDCPY /** * The strendcpy function is a buffer-overrun-safe replacement for * strcpy, strcat, and a more efficient replacement for strlcpy and * strlcat. * * Unless there is no space left in the buffer (dst >= end), the result * will always be NUL terminated. * * @param dst * The position within the destination string buffer to be copied into. * @param src * The string to be copied into the buffer. * @param end * The end of the string buffer being copied into. In most cases * this is of the form "buffer + sizeof(buffer)", a constant which * may be calculated at compile time. * @returns * A pointer into the buffer where at the NUL terminator of the * string in the buffer. EXCEPT when an overrun would occur, in * which case the \a end parameter is returned. * * @note * The return value is where the next string would be written into the * buffer. For example, un-safe code such as * * strcat(strcpy(buffer, "Hello, "), "World\n"); * * can be safely replaced by * * strendcpy(strendcpy(buffer, "Hello, ", buffer + sizeof(buffer)), * "World\n", buffer + sizeof(buffer)); * * and overruns will be handled safely. Similarly, more complex string * manipulations can be written * * char buffer[100]; * char *bp = buffer; * bp = strendcpy(bp, "Hello, ", buffer + sizeof(buffer)); * bp = strendcpy(bp, "World!\n", buffer + sizeof(buffer)); * * all that is required to test for an overrun is * * if (bp == buffer + sizeof(buffer)) * fprintf(stderr, "Overrun!\n"); * * On the plus side, there is only one functionto remember, not two, * replacing both strcpy and strcat. * * There have been some quite viable replacements for strcpy and strcat * in the BSD strlcpy and strlcat functions. These functions are * indeed buffer-ovrrun-safe but they suffer from doing too much work * (and touching too much memory) in the case of overruns. * * Code such as * * strlcpy(buffer, "Hello, ", sizeof(buffer)); * strlcat(buffer, "World!\n", sizeof(buffer)); * * suffers from O(n**2) problem, constantly re-tracing the initial * portions of the buffer. In addition, in the case of overruns, the * BSD versions of these functions return how big the buffer should * have been. This functionality is rarely used, but still requires * the \a src to be traversed all the way to the NUL (and it could be * megabytes away) before they can return. The strendcpy function does * not suffer from either of these performance problems. */ char *strendcpy(char *dst, const char *src, const char *end); #endif #undef strcat #define strcat strcat_is_unsafe__use_strendcat_instead@ #undef strcpy #define strcpy strcpy_is_unsafe__use_strendcpy_instead@ #ifndef HAVE_MEMMEM void *memmem(const void *, size_t, const void *, size_t); #endif void *memmem_replacement(const void *, size_t, const void *, size_t); // It is possible memmem is present, but severely broken. See the GNU // libc memmem(3) man page for just how broken it can get. #define memmem memmem_replacement } #endif // COMMON_AC_STRING_H