This is an old revision of the document!
Download concat.c (shown below).
This code is used in popa3d, passwdqc, and blists.
Back to other source code snippets and frameworks placed in the public domain.
/* * concat() - allocate memory and safely concatenate strings in portable C * (and C++ if you like). * * This code deals gracefully with potential integer overflows (perhaps when * input strings are maliciously long), as well as with input strings changing * from under it (perhaps because of misbehavior of another thread). It does * not depend on non-portable functions such as snprintf() and asprintf(). * * Written by Solar Designer <solar at openwall.com> and placed in the * public domain. * * Originally written for and currently maintained as a part of popa3d, * a POP3 server: * * http://www.openwall.com/popa3d/ */ #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <limits.h> char *concat(const char *s1, ...) { va_list args; const char *s; char *p, *result; size_t l, m, n; m = n = strlen(s1); va_start(args, s1); while ((s = va_arg(args, char *))) { l = strlen(s); if ((m += l) < l) break; } va_end(args); if (s || m >= INT_MAX) return NULL; result = (char *)malloc(m + 1); if (!result) return NULL; memcpy(p = result, s1, n); p += n; va_start(args, s1); while ((s = va_arg(args, char *))) { l = strlen(s); if ((n += l) < l || n > m) break; memcpy(p, s, l); p += l; } va_end(args); if (s || m != n || p != result + n) { free(result); return NULL; } *p = 0; return result; } #ifdef TEST #include <stdio.h> int main(int argc, char **argv) { puts(concat(argv[0], argv[1], argv[2], argv[3], NULL)); return 0; } #endif
Back to other source code snippets and frameworks placed in the public domain.