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