1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Test for sprintf 5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #include <apitest.h> 9 #include <apitest_guard.h> 10 11 #define WIN32_NO_STATUS 12 #include <stdio.h> 13 #include <tchar.h> 14 #include <pseh/pseh2.h> 15 #include <ndk/mmfuncs.h> 16 #include <ndk/rtlfuncs.h> 17 18 #ifdef _MSC_VER 19 #pragma warning(disable:4778) // unterminated format string '%' 20 #elif defined(__GNUC__) 21 #pragma GCC diagnostic ignored "-Wformat" 22 #pragma GCC diagnostic ignored "-Wformat-zero-length" 23 #pragma GCC diagnostic ignored "-Wnonnull" 24 #if __GNUC__ >= 7 25 #pragma GCC diagnostic ignored "-Wformat-overflow" 26 #endif 27 #endif 28 29 /* NOTE: This test is not only used for all the CRT apitests, but also for 30 * user32's wsprintf. Make sure to test them all */ 31 START_TEST(sprintf) 32 { 33 int Length; 34 CHAR Buffer[128]; 35 PCHAR String; 36 37 /* basic parameter tests */ 38 StartSeh() 39 Length = sprintf(NULL, NULL); 40 EndSeh(STATUS_ACCESS_VIOLATION); 41 42 StartSeh() 43 Length = sprintf(NULL, ""); 44 ok_int(Length, 0); 45 #if TEST_CRTDLL || TEST_USER32 46 EndSeh(STATUS_ACCESS_VIOLATION); 47 #else 48 EndSeh(STATUS_SUCCESS); 49 #endif 50 51 StartSeh() 52 Length = sprintf(NULL, "Hello"); 53 ok_int(Length, 5); 54 #if TEST_CRTDLL || TEST_USER32 55 EndSeh(STATUS_ACCESS_VIOLATION); 56 #else 57 EndSeh(STATUS_SUCCESS); 58 #endif 59 60 /* some basic formats */ 61 Length = sprintf(Buffer, "abcde"); 62 ok_str(Buffer, "abcde"); 63 ok_int(Length, 5); 64 65 Length = sprintf(Buffer, "%%"); 66 ok_str(Buffer, "%"); 67 ok_int(Length, 1); 68 69 Length = sprintf(Buffer, "%"); 70 ok_str(Buffer, ""); 71 ok_int(Length, 0); 72 73 Length = sprintf(Buffer, "%%%"); 74 ok_str(Buffer, "%"); 75 ok_int(Length, 1); 76 77 Length = sprintf(Buffer, "%d", 8); 78 ok_str(Buffer, "8"); 79 ok_int(Length, 1); 80 81 Length = sprintf(Buffer, "%s", "hello"); 82 ok_str(Buffer, "hello"); 83 ok_int(Length, 5); 84 85 /* field width for %s */ 86 Length = sprintf(Buffer, "%8s", "hello"); 87 ok_str(Buffer, " hello"); 88 ok_int(Length, 8); 89 90 Length = sprintf(Buffer, "%4s", "hello"); 91 ok_str(Buffer, "hello"); 92 ok_int(Length, 5); 93 94 Length = sprintf(Buffer, "%-8s", "hello"); 95 ok_str(Buffer, "hello "); 96 ok_int(Length, 8); 97 98 Length = sprintf(Buffer, "%-5s", "hello"); 99 ok_str(Buffer, "hello"); 100 ok_int(Length, 5); 101 102 Length = sprintf(Buffer, "%0s", "hello"); 103 ok_str(Buffer, "hello"); 104 ok_int(Length, 5); 105 106 Length = sprintf(Buffer, "%-0s", "hello"); 107 ok_str(Buffer, "hello"); 108 ok_int(Length, 5); 109 110 Length = sprintf(Buffer, "%*s", -8, "hello"); 111 #ifdef TEST_USER32 112 ok_str(Buffer, "*s"); 113 ok_int(Length, 2); 114 #else 115 ok_str(Buffer, "hello "); 116 ok_int(Length, 8); 117 #endif 118 119 /* precision for %s */ 120 Length = sprintf(Buffer, "%.s", "hello"); 121 ok_str(Buffer, ""); 122 ok_int(Length, 0); 123 124 Length = sprintf(Buffer, "%.0s", "hello"); 125 ok_str(Buffer, ""); 126 ok_int(Length, 0); 127 128 Length = sprintf(Buffer, "%.10s", "hello"); 129 ok_str(Buffer, "hello"); 130 ok_int(Length, 5); 131 132 Length = sprintf(Buffer, "%.5s", "hello"); 133 ok_str(Buffer, "hello"); 134 ok_int(Length, 5); 135 136 Length = sprintf(Buffer, "%.4s", "hello"); 137 ok_str(Buffer, "hell"); 138 ok_int(Length, 4); 139 140 StartSeh() 141 Length = sprintf(Buffer, "%.*s", -1, "hello"); 142 #ifdef TEST_USER32 143 ok_str(Buffer, "*s"); 144 ok_int(Length, 2); 145 #else 146 ok_str(Buffer, "hello"); 147 ok_int(Length, 5); 148 #endif 149 EndSeh(STATUS_SUCCESS); 150 151 String = AllocateGuarded(6); 152 if (!String) 153 { 154 skip("Guarded allocation failure\n"); 155 return; 156 } 157 158 strcpy(String, "hello"); 159 StartSeh() 160 Length = sprintf(Buffer, "%.8s", String); 161 ok_str(Buffer, "hello"); 162 ok_int(Length, 5); 163 EndSeh(STATUS_SUCCESS); 164 165 StartSeh() 166 Length = sprintf(Buffer, "%.6s", String); 167 ok_str(Buffer, "hello"); 168 ok_int(Length, 5); 169 EndSeh(STATUS_SUCCESS); 170 171 StartSeh() 172 Length = sprintf(Buffer, "%.5s", String); 173 ok_str(Buffer, "hello"); 174 ok_int(Length, 5); 175 EndSeh(STATUS_SUCCESS); 176 177 StartSeh() 178 Length = sprintf(Buffer, "%.4s", String); 179 ok_str(Buffer, "hell"); 180 ok_int(Length, 4); 181 EndSeh(STATUS_SUCCESS); 182 183 String[5] = '!'; 184 StartSeh() 185 Length = sprintf(Buffer, "%.5s", String); 186 ok_str(Buffer, "hello"); 187 ok_int(Length, 5); 188 #ifdef TEST_USER32 189 EndSeh(STATUS_ACCESS_VIOLATION); 190 #else 191 EndSeh(STATUS_SUCCESS); 192 #endif 193 194 StartSeh() 195 Length = sprintf(Buffer, "%.6s", String); 196 ok_str(Buffer, "hello!"); 197 ok_int(Length, 6); 198 #ifdef TEST_USER32 199 EndSeh(STATUS_ACCESS_VIOLATION); 200 #else 201 EndSeh(STATUS_SUCCESS); 202 #endif 203 204 StartSeh() 205 Length = sprintf(Buffer, "%.*s", 5, String); 206 #ifdef TEST_USER32 207 ok_str(Buffer, "*s"); 208 ok_int(Length, 2); 209 #else 210 ok_str(Buffer, "hello"); 211 ok_int(Length, 5); 212 #endif 213 EndSeh(STATUS_SUCCESS); 214 215 StartSeh() 216 Length = sprintf(Buffer, "%.*s", 6, String); 217 #ifdef TEST_USER32 218 ok_str(Buffer, "*s"); 219 ok_int(Length, 2); 220 #else 221 ok_str(Buffer, "hello!"); 222 ok_int(Length, 6); 223 #endif 224 EndSeh(STATUS_SUCCESS); 225 226 /* both field width and precision */ 227 StartSeh() 228 Length = sprintf(Buffer, "%8.5s", String); 229 ok_str(Buffer, " hello"); 230 ok_int(Length, 8); 231 #ifdef TEST_USER32 232 EndSeh(STATUS_ACCESS_VIOLATION); 233 #else 234 EndSeh(STATUS_SUCCESS); 235 #endif 236 237 StartSeh() 238 Length = sprintf(Buffer, "%-*.6s", -8, String); 239 #ifdef TEST_USER32 240 ok_str(Buffer, "*.6s"); 241 ok_int(Length, 4); 242 #else 243 ok_str(Buffer, "hello! "); 244 ok_int(Length, 8); 245 #endif 246 EndSeh(STATUS_SUCCESS); 247 248 StartSeh() 249 Length = sprintf(Buffer, "%*.*s", -8, 6, String); 250 #ifdef TEST_USER32 251 ok_str(Buffer, "*.*s"); 252 ok_int(Length, 4); 253 #else 254 ok_str(Buffer, "hello! "); 255 ok_int(Length, 8); 256 #endif 257 EndSeh(STATUS_SUCCESS); 258 259 FreeGuarded(String); 260 } 261