/*------------------------------------------------------------------ * test_vsnprintf_s * File 'wchar/vsnprintf_s.c' * Lines executed:75.86% of 29 * *------------------------------------------------------------------ */ #include "test_private.h" #include "safe_str_lib.h" #include #ifdef HAVE_VSNPRINTF_S #define HAVE_NATIVE 1 #else #define HAVE_NATIVE 0 #endif #include "test_msvcrt.h" #if defined(_WIN32) && defined(HAVE_VSNPRINTF_S) #define USE_MSVCRT int vsnprintf_s(char *dest, size_t dmax, size_t maxcount, const char *fmt, va_list arglist); #endif #define LEN (128) static char str1[LEN]; static char str2[LEN]; static inline int vtprintf_s(char *restrict dest, rsize_t dmax, const char *restrict fmt, ...) BOS_CHK(dest) BOS_NULL(fmt); #ifndef HAVE_CT_BOS_OVR static inline int vtprintf_s_chk(char *restrict dest, rsize_t dmax, rsize_t destbos, const char *restrict fmt, ...) BOS_CHK(dest) BOS_NULL(fmt); #endif int test_vsnprintf_s(void); static inline int vtprintf_s(char *restrict dest, rsize_t dmax, const char *restrict fmt, ...) { int rc; va_list ap; va_start(ap, fmt); #ifdef USE_MSVCRT rc = vsnprintf_s(dest, dmax, 20, fmt, ap); #else rc = vsnprintf_s(dest, dmax, fmt, ap); #endif va_end(ap); return rc; } #ifndef HAVE_CT_BOS_OVR static inline int vtprintf_s_chk(char *restrict dest, rsize_t dmax, rsize_t destbos, const char *restrict fmt, ...) { int rc; va_list ap; va_start(ap, fmt); #ifdef USE_MSVCRT rc = vsnprintf_s(dest, dmax, 20, fmt, ap); #else rc = _vsnprintf_s_chk(dest, dmax, destbos, fmt, ap); #endif va_end(ap); return rc; } #endif int test_vsnprintf_s(void) { errno_t rc; int32_t len2; int32_t len3; int errs = 0; #ifndef HAVE_CT_BOS_OVR int have_wine = 0; #endif /*--------------------------------------------------*/ /* not testable rc = vtprintf_s(str1, LEN, "%s", NULL); NEGERR(ESNULLP) */ /*--------------------------------------------------*/ print_msvcrt(use_msvcrt); #ifndef HAVE_CT_BOS_OVR EXPECT_BOS("empty dest or dmax") rc = vtprintf_s(str1, 0, "%s", str2); init_msvcrt(rc == -ESZEROL, &use_msvcrt); NEGERR_MSVC(ESZEROL, EOF); /* wine msvcrt doesn't check fmt==NULL */ #if !(defined(_WINE_MSVCRT) && defined(TEST_MSVCRT) && \ defined(HAVE_VSNPRINTF_S)) EXPECT_BOS("empty fmt") rc = vtprintf_s(str1, LEN, NULL); NEGERR_MSVC(ESNULLP, EOF); #else printf("Using wine\n"); have_wine = 1; #endif EXPECT_BOS("dest overflow") rc = vtprintf_s(str1, (RSIZE_MAX_STR + 1), "%s", str2); if (have_wine) { ERR(EOF); } else { NEGERR_MSVC(ESLEMAX, 0); } if (_BOS_KNOWN(str1)) { EXPECT_BOS("dest overflow") rc = vtprintf_s_chk(str1, LEN + 1, _BOS_KNOWN(str1), "%s", str2); NEGERR_MSVC(EOVERFLOW, 0); /* dmax exceeds dest */ CHECK_SLACK(str1, LEN); /* cleared */ } #endif /*--------------------------------------------------*/ strcpy(str1, "aaaaaaaaaa"); strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 1, "%s", str2); if (!use_msvcrt) { ERR(14); } else { ERR(-1); } EXPNULL(str1) /*--------------------------------------------------*/ strcpy(str1, "aaaaaaaaaa"); strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 2, "%s", str2); if (!use_msvcrt) { ERR(14); } else { ERR(-1); } /*--------------------------------------------------*/ strcpy(str1, "aaaaaaaaaa"); strcpy(str2, "keep it simple"); len2 = strlen(str2); rc = vtprintf_s(str1, 50, "%s", str2); ERR(len2) len3 = strlen(str1); if (len3 != len2) { #ifdef DEBUG int len1 = strlen(str1); debug_printf("%s %u lengths wrong: %d %u %u \n", __FUNCTION__, __LINE__, len1, len2, len3); #endif errs++; } /*--------------------------------------------------*/ str1[0] = '\0'; strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 5, "%s", str2); #ifndef HAVE_MINGW32 NOERRNULL() /* no ENOSPC */ EXPSTR(str1, "keep") #else ERR(-1); EXPSTR(str1, "") #endif /*--------------------------------------------------*/ str1[0] = '\0'; strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 2, "%s", str2); #ifndef HAVE_MINGW32 ERR(14) /* sic! unsafe */ EXPSTR(str1, "k") #else ERR(-1); EXPSTR(str1, "") #endif /*--------------------------------------------------*/ str1[0] = '\0'; strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 20, "%s", str2); NOERRNULL() EXPSTR(str1, str2) /*--------------------------------------------------*/ str1[0] = '\0'; str2[0] = '\0'; rc = vtprintf_s(str1, LEN, "%s", str2); ERR(0) EXPNULL(str1) /*--------------------------------------------------*/ str1[0] = '\0'; strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, LEN, "%s", str2); NOERR() EXPSTR(str1, str2) /*--------------------------------------------------*/ strcpy(str1, "qqweqq"); strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, LEN, "%s", str2); NOERRNULL() EXPSTR(str1, str2) /*--------------------------------------------------*/ strcpy(str1, "1234"); strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 12, "%s", str2); #ifndef HAVE_MINGW32 ERR(14) /* sic! unsafe */ #else ERR(-1); EXPSTR(str1, "") #endif /*--------------------------------------------------*/ strcpy(str1, "1234"); strcpy(str2, "keep it simple"); rc = vtprintf_s(str1, 52, "%s", str2); NOERRNULL() EXPSTR(str1, str2) /*--------------------------------------------------*/ strcpy(str1, "12345678901234567890"); rc = vtprintf_s(str1, 8, "%s", &str1[7]); #ifndef HAVE_MINGW32 ERR(13) /* sic! unsafe */ #else ERR(-1); EXPSTR(str1, "") #endif /*--------------------------------------------------*/ strcpy(str1, "123456789"); rc = vtprintf_s(str1, 9, "%s", &str1[8]); ERR(1) /* overlapping allowed */ EXPSTR(str1, "9") /*--------------------------------------------------*/ strcpy(str2, "123"); strcpy(str1, "keep it simple"); rc = vtprintf_s(str2, 31, "%s", &str1[0]); NOERRNULL() EXPSTR(str2, "keep it simple") /*--------------------------------------------------*/ strcpy(str2, "1234"); strcpy(str1, "56789"); rc = vtprintf_s(str2, 10, "%s", str1); NOERRNULL() EXPSTR(str2, "56789") /*--------------------------------------------------*/ return (errs); } #ifndef __KERNEL__ /* simple hack to get this to work for both userspace and Linux kernel, until a better solution can be created. */ int main(void) { return (test_vsnprintf_s()); } #endif