From a17b7c8c14696314f1b298538ffcfae4e787a19f Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 31 May 2019 11:17:11 -0400 Subject: [PATCH] Fixed build errors and simplified error handling in test/noinitwrongthread.c. Now to test this at runtime on all platforms. --- common/alloc.c | 1 + sharedbits/strsafe_impl.h | 19 ++++++++++++++++--- test/lib/testingpriv.c | 3 +++ test/noinitwrongthread.c | 9 ++++++--- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/common/alloc.c b/common/alloc.c index d20bf370..4a61a560 100644 --- a/common/alloc.c +++ b/common/alloc.c @@ -1,4 +1,5 @@ // 16 may 2019 +#include #include #include #include diff --git a/sharedbits/strsafe_impl.h b/sharedbits/strsafe_impl.h index 20308632..357e760a 100644 --- a/sharedbits/strsafe_impl.h +++ b/sharedbits/strsafe_impl.h @@ -3,12 +3,17 @@ #include "start.h" +#ifdef sharedbitsInternalError +#define sharedbitsprivInternalError sharedbitsInternalError +#else +#define sharedbitsprivInternalError sharedbitsPrefixName(InternalError) #ifdef sharedbitsStatic -sharedBitsStatic +sharedbitsStatic #else extern #endif -void sharedbitsPrefixName(InternalError)(const char *fmt, ...); +void sharedbitsprivInternalError(const char *fmt, ...); +#endif #ifdef sharedbitsStatic sharedbitsStatic @@ -43,11 +48,19 @@ char *sharedbitsPrefixName(Strncpy)(char *dest, const char *src, size_t n) memset(dest, '\0', n * sizeof (char)); err = strncpy_s(dest, n, src, _TRUNCATE); if (err != 0 && err != STRUNCATE) - sharedbitsStaticName(InternalError)("error calling strncpy_s(): %s (%d)", strerror(err), err); + // Yes folks, apparently strerror() is unsafe (it's not reentrant, but that's not the point of the MSVC security functions; that's about buffer overflows, and as you'll soon see there really is no need for what the "safe' version is given reentrancy concerns), and not only that, but the replacement, strerror_s(), requires copying and allocation! it's almost like they were TRYING to shove as many error conditions as possible in! + // Oh, and you can't just use _sys_errlist[] to bypass this, because even that has a deprecation warning, telling you to use strerror() instead, which in turn sends you back to strerror_s()! + // Of course, the fact _sys_errlist[] is a thing and that it's deprecated out of security and not reentrancy shows that the error strings returned by strerror()/strerror_s() are static and unchanging throughout the lifetime of the program, so a truly reentrant strerror_s() would just return the raw const string array directly, or a placeholder like "unknown error" otherwise, but that would be too easy! + // And even better, there's no way to get the length of the error message, so you can't even dynamically allocate a large enough buffer if you wanted to! + // (Furthermore, cppreference.com says there's strerrorlen_s(), but a) fuck C11, and b) MSDN does not concur.) + // So, alas, you'll have to live with just having the error code; sorry. + sharedbitsprivInternalError("error calling strncpy_s(): %d", err); return dest; #else return strncpy(dest, src, n); #endif } +#undef sharedbitsprivInternalError + #include "end.h" diff --git a/test/lib/testingpriv.c b/test/lib/testingpriv.c index 3cb591f6..3891cf84 100644 --- a/test/lib/testingpriv.c +++ b/test/lib/testingpriv.c @@ -1,4 +1,5 @@ // 19 may 2019 +#include #include #include #include @@ -24,7 +25,9 @@ void testingprivInternalError(const char *fmt, ...) #define sharedbitsPrefix testingprivImpl #define sharedbitsStatic static +#define sharedbitsInternalError testingprivInternalError #include "../../sharedbits/strsafe_impl.h" +#undef sharedbitsInternalError #undef sharedbitsStatic #undef sharedbitsPrefix diff --git a/test/noinitwrongthread.c b/test/noinitwrongthread.c index 95071b22..129ef276 100644 --- a/test/noinitwrongthread.c +++ b/test/noinitwrongthread.c @@ -1,4 +1,6 @@ // 28 may 2019 +#include +#include #include #include #include "lib/thread.h" @@ -28,6 +30,7 @@ static char caseErrorEncodingError[] = "encoding error while handling other case static void privInternalError(const char *fmt, ...) { va_list ap, ap2; + int n; va_start(ap, fmt); va_copy(ap2, ap); @@ -44,7 +47,7 @@ static void privInternalError(const char *fmt, ...) va_end(ap); return; } - privVsnprintf(otherError, n + 1, fmt, ap); + privVsnprintf(caseError, n + 1, fmt, ap); va_end(ap); } @@ -169,7 +172,7 @@ testingTestInSet(beforeTests, FunctionsFailBeforeInit) if (caseError != caseErrorMemoryExhausted && caseError != caseErrorEncodingError) free(caseError); caseError = NULL; - testingTFailNow(); + testingTFailNow(t); } reportCases(t, cases); freeCases(cases); @@ -219,7 +222,7 @@ testingTest(FunctionsFailOnWrongThread) if (caseError != caseErrorMemoryExhausted && caseError != caseErrorEncodingError) free(caseError); caseError = NULL; - testingTFailNow(); + testingTFailNow(t); } reportCases(t, cases); freeCases(cases);