mutt stable branch with some hacks
at jcs 94 lines 2.5 kB view raw
1/* 2 * Copyright (C) 2010 Michael R. Elkins <me@mutt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#include <stdio.h> 20#include "lib.h" 21 22/* NOTE: Currently there is no check in configure.ac for vasprintf(3). the 23 * undefined behavior of the error condition makes it difficult to write a safe 24 * version using it. 25 */ 26 27#ifdef HAVE_VASPRINTF 28int safe_asprintf (char **strp, const char *fmt, ...) 29{ 30 va_list ap; 31 int n; 32 33 va_start (ap, fmt); 34 n = vasprintf (strp, fmt, ap); 35 va_end (ap); 36 37 /* GNU libc man page for vasprintf(3) states that the value of *strp 38 * is undefined when the return code is -1. 39 */ 40 if (n < 0) 41 { 42 mutt_error _("Out of memory!"); 43 sleep (1); 44 mutt_exit (1); 45 } 46 47 if (n == 0) 48 { 49 /* Mutt convention is to use NULL for 0-length strings */ 50 FREE (strp); /* __FREE_CHECKED__ */ 51 } 52 53 return n; 54} 55#else 56/* Allocate a C-string large enough to contain the formatted string. 57 * This is essentially malloc+sprintf in one. 58 */ 59int safe_asprintf (char **strp, const char *fmt, ...) 60{ 61 int rlen = STRING; 62 int n; 63 64 *strp = safe_malloc (rlen); 65 for (;;) 66 { 67 va_list ap; 68 va_start (ap, fmt); 69 n = vsnprintf (*strp, rlen, fmt, ap); 70 va_end (ap); 71 if (n < 0) 72 { 73 FREE (strp); /* __FREE_CHECKED__ */ 74 return n; 75 } 76 77 if (n < rlen) 78 { 79 /* reduce space to just that which was used. note that 'n' does not 80 * include the terminal nul char. 81 */ 82 if (n == 0) /* convention is to use NULL for zero-length strings. */ 83 FREE (strp); /* __FREE_CHECKED__ */ 84 else if (n != rlen - 1) 85 safe_realloc (strp, n + 1); 86 return n; 87 } 88 /* increase size and try again */ 89 rlen = n + 1; 90 safe_realloc (strp, rlen); 91 } 92 /* not reached */ 93} 94#endif /* HAVE_ASPRINTF */