diff options
author | Howard Hinnant <hhinnant@apple.com> | 2013-04-02 15:46:31 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2013-04-02 15:46:31 +0000 |
commit | a1985ebbc84c8f8536ce9e2003d43c4aa2603a56 (patch) | |
tree | 0eea1f0c7395e3bce93e8dedde72fcba5dd5a965 | |
parent | 9d00ed5d8749f472e63ca7e5a510da2ee58f9dbd (diff) | |
download | external_libcxx-a1985ebbc84c8f8536ce9e2003d43c4aa2603a56.tar.gz external_libcxx-a1985ebbc84c8f8536ce9e2003d43c4aa2603a56.tar.bz2 external_libcxx-a1985ebbc84c8f8536ce9e2003d43c4aa2603a56.zip |
Reference: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130325/077131.html
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@178544 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | src/support/win32/support.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/support/win32/support.cpp b/src/support/win32/support.cpp index 9e85077a7..2139a3f85 100644 --- a/src/support/win32/support.cpp +++ b/src/support/win32/support.cpp @@ -23,14 +23,23 @@ int asprintf(char **sptr, const char *__restrict fmt, ...) va_end(ap); return result; } + +// Like sprintf, but when return value >= 0 it returns a pointer to a malloc'd string in *sptr. +// If return >= 0, use free to delete *sptr. int vasprintf( char **sptr, const char *__restrict fmt, va_list ap ) { *sptr = NULL; - int count = vsnprintf( *sptr, 0, fmt, ap ); - if( (count >= 0) && ((*sptr = (char*)malloc(count+1)) != NULL) ) - { - vsprintf( *sptr, fmt, ap ); - sptr[count] = '\0'; + int count = vsnprintf( NULL, 0, fmt, ap ); // Query the buffer size required. + if( count >= 0 ) { + char* p = static_cast<char*>(malloc(count+1)); // Allocate memory for it and the terminator. + if ( p == NULL ) + return -1; + if ( vsnprintf( p, count+1, fmt, ap ) == count ) // We should have used exactly what was required. + *sptr = p; + else { // Otherwise something is wrong, likely a bug in vsnprintf. If so free the memory and report the error. + free(p); + return -1; + } } return count; |