diff options
author | Robert E. McGrath <mcgrath@ncsa.uiuc.edu> | 2004-06-18 21:52:18 (GMT) |
---|---|---|
committer | Robert E. McGrath <mcgrath@ncsa.uiuc.edu> | 2004-06-18 21:52:18 (GMT) |
commit | 176433836aed77419712005be636fbd41fae7bc8 (patch) | |
tree | 68abb1029dc4ac290260ed68ea4cb6e149296607 /tools/lib/h5tools_str.c | |
parent | f249eed71d4b646bc57a43f28e32f3c2d9d71050 (diff) | |
download | hdf5-176433836aed77419712005be636fbd41fae7bc8.zip hdf5-176433836aed77419712005be636fbd41fae7bc8.tar.gz hdf5-176433836aed77419712005be636fbd41fae7bc8.tar.bz2 |
[svn-r8709] Purpose:
Bug fix for mozilla 145
Description:
h5dump output truncated on SGI
Solution:
See message for 1.6 branch
Platforms tested:
verbena
Misc. update:
Diffstat (limited to 'tools/lib/h5tools_str.c')
-rw-r--r-- | tools/lib/h5tools_str.c | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 6656c81..9faba55 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -111,6 +111,12 @@ h5tools_str_len(h5tools_str_t *str) * * Modifications: * + * Major change: need to check results of vsnprintf to + * handle errors, empty format, and overflows. + * + * Programmer: REMcG Matzke + * June 16, 2004 + * *------------------------------------------------------------------------- */ char * @@ -129,24 +135,50 @@ h5tools_str_append(h5tools_str_t *str/*in,out*/, const char *fmt, ...) str->len = 0; } - while (1) { + if (strlen(fmt) == 0) { + /* nothing to print */ + va_end(ap); + return str->s; + } + + /* Format the arguments and append to the value already in `str' */ + while (1) { + /* How many bytes available for new value, counting the new NUL */ size_t avail = str->nalloc - str->len; - size_t nchars = (size_t)HDvsnprintf(str->s + str->len, avail, fmt, ap); - if (nchars < avail) { - /* success */ - str->len += nchars; - break; - } - - /* Try again with twice as much space */ - str->nalloc *= 2; - str->s = realloc(str->s, str->nalloc); - assert(str->s); - } + int nchars = HDvsnprintf(str->s + str->len, avail, fmt, ap); - va_end(ap); - return str->s; + if (nchars<0) { + /* failure, such as bad format */ + va_end(ap); + return NULL; + } + + if ((size_t)nchars>=avail || + (0==nchars && (strcmp(fmt,"%s") ))) { + /* Truncation return value as documented by C99, or zero return value with either of the + * following conditions, each of which indicates that the proper C99 return value probably + * should have been positive when the format string is + * something other than "%s" + * Alocate at least twice as much space and try again. + */ + size_t newsize = MAX(str->len+nchars+1, 2*str->nalloc); + assert(newsize > str->nalloc); /*overflow*/ +#ifndef H5_HAVE_VSNPRINTF + /* If we even made it this far... the HDvsnprintf() clobbered memory: SIGSEGV probable*/ + abort(); +#endif + str->s = realloc(str->s, newsize); + assert(str->s); + str->nalloc = newsize; + } else { + /* Success */ + str->len += nchars; + break; + } + } + va_end(ap); + return str->s; } /*------------------------------------------------------------------------- |