X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/38914d5a514fffc34111a33a01a55bd42e135a54..fd5907ffd9b0785bb6eb6f2546101623b23827c5:/tests/strings/vararg.cpp diff --git a/tests/strings/vararg.cpp b/tests/strings/vararg.cpp index a5677c6c68..c7db2aa23c 100644 --- a/tests/strings/vararg.cpp +++ b/tests/strings/vararg.cpp @@ -42,6 +42,7 @@ private: #endif CPPUNIT_TEST( Sscanf ); CPPUNIT_TEST( RepeatedPrintf ); + CPPUNIT_TEST( ArgsValidation ); CPPUNIT_TEST_SUITE_END(); void StringPrintf(); @@ -51,6 +52,7 @@ private: #endif void Sscanf(); void RepeatedPrintf(); + void ArgsValidation(); DECLARE_NO_COPY_CLASS(VarArgTestCase) }; @@ -183,3 +185,78 @@ void VarArgTestCase::RepeatedPrintf() s = wxString::Format("buffer %s, len %d", buffer, (int)wxStrlen(buffer)); CPPUNIT_ASSERT_EQUAL("buffer hi, len 2", s); } + +void VarArgTestCase::ArgsValidation() +{ + void *ptr = this; + int written; + short int swritten; + + // these are valid: + wxString::Format("a string(%s,%s), ptr %p, int %i", + wxString(), "foo", "char* as pointer", 1); + + // Microsoft has helpfully disabled support for "%n" in their CRT by + // default starting from VC8 and somehow even calling + // _set_printf_count_output() doesn't help here, so don't use "%n" at all + // with it. +#if wxCHECK_VISUALC_VERSION(8) + #define wxNO_PRINTF_PERCENT_N +#endif // VC8+ + + // Similarly, many modern Linux distributions ship with g++ that uses + // -D_FORTIFY_SOURCE=2 flag by default and this option prevents "%n" from + // being used in a string outside of read-only memory, meaning that it + // can't be used in wxString to which we (may, depending on build options) + // assign it, so also disable testing of "%n" in this case lest we die with + // an abort inside vswprintf(). +#if defined(_FORTIFY_SOURCE) + #if _FORTIFY_SOURCE >= 2 + #define wxNO_PRINTF_PERCENT_N + #endif +#endif + +#ifndef wxNO_PRINTF_PERCENT_N + wxString::Format("foo%i%n", 42, &written); + CPPUNIT_ASSERT_EQUAL( 5, written ); +#endif + + // but these are not: + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i: too many arguments", 42, 1, 2, 3) ); + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%i", "foo") ); + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", (void*)this) ); + + // for some reason assert is not generated with VC6, don't know what's + // going there so disable it for now to make the test suite pass when using + // this compiler until someone has time to debug this (FIXME-VC6) +#ifndef __VISUALC6__ + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%d", ptr) ); +#endif + + // we don't check wxNO_PRINTF_PERCENT_N here as these expressions should + // result in an assert in our code before the CRT functions are even called + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", &written) ); + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%n", ptr) ); + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("foo%i%n", 42, &swritten) ); + + // the following test (correctly) fails at compile-time with + // and it also (wrongly) fails when using VC6 because it somehow tries to + // use (inaccessible) VarArgTestCase copy ctor (FIXME-VC6) +#if !defined(HAVE_TYPE_TRAITS) && !defined(HAVE_TR1_TYPE_TRAITS) && \ + !defined(__VISUALC6__) + VarArgTestCase& somePOD = *this; + WX_ASSERT_FAILS_WITH_ASSERT( wxString::Format("%s", somePOD) ); +#endif + + // %c should accept integers too + wxString::Format("%c", 80); + wxString::Format("%c", wxChar(80) + wxChar(1)); + + // check size_t handling + size_t len = sizeof(*this); +#ifdef __WXMSW__ + wxString::Format("%Iu", len); +#else + wxString::Format("%zu", len); +#endif +}