diff --git a/src/common/string.cpp b/src/common/string.cpp index 622da992a2..0af2b0d885 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -2060,17 +2060,6 @@ static int DoStringPrintfV(wxString& str, // buffer were large enough (newer standards such as Unix98) if ( len < 0 ) { - // NB: wxVsnprintf() may call either wxCRT_VsnprintfW or - // wxCRT_VsnprintfA in UTF-8 build; wxUSE_WXVSNPRINTF - // is true if *both* of them use our own implementation, - // otherwise we can't be sure -#if wxUSE_WXVSNPRINTF - // we know that our own implementation of wxVsnprintf() returns -1 - // only for a format error - thus there's something wrong with - // the user's format string - buf[0] = '\0'; - return -1; -#else // possibly using system version // assume it only returns error if there is not enough space, but // as we don't know how much we need, double the current size of // the buffer @@ -2082,16 +2071,9 @@ static int DoStringPrintfV(wxString& str, // still not enough, as we don't know how much we need, double the // current size of the buffer size *= 2; -#endif // wxUSE_WXVSNPRINTF/!wxUSE_WXVSNPRINTF } else if ( len >= size ) { -#if wxUSE_WXVSNPRINTF - // we know that our own implementation of wxVsnprintf() returns - // size+1 when there's not enough space but that's not the size - // of the required buffer! - size *= 2; // so we just double the current size of the buffer -#else // some vsnprintf() implementations NUL-terminate the buffer and // some don't in len == size case, to be safe always add 1 // FIXME: I don't quite understand this comment. The vsnprintf @@ -2100,7 +2082,6 @@ static int DoStringPrintfV(wxString& str, // So OF COURSE you need to add 1 to get the right buffer size. // The following line is definitely correct, no question. size = len + 1; -#endif } else // ok, there was enough space { diff --git a/src/common/wxprintf.cpp b/src/common/wxprintf.cpp index bc022d421e..06787963a2 100644 --- a/src/common/wxprintf.cpp +++ b/src/common/wxprintf.cpp @@ -25,6 +25,7 @@ #include "wx/private/wxprintf.h" +#include // ============================================================================ // printf() implementation @@ -106,6 +107,9 @@ static int wxDoVsnprintf(CharType *buf, size_t lenMax, if (parser.posarg_present && parser.nonposarg_present) { buf[0] = 0; + // Indicate to the caller that it's an unrecoverable error and not just + // due to the buffer being too small. + errno = EINVAL; return -1; // format strings with both positional and } // non-positional conversion specifier are unsupported !! @@ -131,6 +135,7 @@ static int wxDoVsnprintf(CharType *buf, size_t lenMax, if (!ok) { buf[0] = 0; + errno = EINVAL; return -1; } @@ -154,7 +159,7 @@ static int wxDoVsnprintf(CharType *buf, size_t lenMax, if (lenCur == lenMax) { buf[lenMax - 1] = 0; - return lenMax+1; // not enough space in the output buffer ! + return -1; // not enough space in the output buffer ! } // process this specifier directly in the output buffer @@ -163,7 +168,7 @@ static int wxDoVsnprintf(CharType *buf, size_t lenMax, if (n == -1) { buf[lenMax-1] = wxT('\0'); // be sure to always NUL-terminate the string - return lenMax+1; // not enough space in the output buffer ! + return -1; // not enough space in the output buffer ! } lenCur += n; @@ -183,7 +188,7 @@ static int wxDoVsnprintf(CharType *buf, size_t lenMax, if (buf[lenCur]) { buf[lenCur] = 0; - return lenMax+1; // not enough space in the output buffer ! + return -1; // not enough space in the output buffer ! } // Don't do: diff --git a/tests/strings/vsnprintf.cpp b/tests/strings/vsnprintf.cpp index ccc43f77ba..53f48c3e2e 100644 --- a/tests/strings/vsnprintf.cpp +++ b/tests/strings/vsnprintf.cpp @@ -52,11 +52,10 @@ int r; // Another helper which takes the size explicitly instead of using MAX_TEST_LEN // // NOTE: this macro is used also with too-small buffers (see Miscellaneous()) -// test function, thus the return value can be > size and thus we +// test function, thus the return value can be either -1 or > size and we // cannot check if r == (int)wxStrlen(buf) #define CMPTOSIZE(buffer, size, failuremsg, expected, fmt, ...) \ r=wxSnprintf(buffer, size, fmt, ##__VA_ARGS__); \ - CHECK( r > 0 ); \ INFO(failuremsg); \ CHECK( buffer == wxString(expected).Left(size - 1) ) @@ -340,8 +339,10 @@ TEST_CASE_METHOD(VsnprintfTestCase, "Vsnprintf::WrongFormatStrings", "[vsnprintf wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$d %3$d"), 1, 2, 3) ); // positional and non-positionals in the same format string: + errno = 0; r = wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$d %d %3$d"), 1, 2, 3); CHECK( r == -1 ); + CHECK( errno == EINVAL ); } // BigToSmallBuffer() test case helper: @@ -392,7 +393,6 @@ void VsnprintfTestCase::DoBigToSmallBuffer(T *buffer, int size) wxString expected = wxString(wxT("unicode string/char: unicode/U -- ansi string/char: ansi/A")).Left(size - 1); - CHECK( r != -1 ); CHECK( expected == buffer ); }