/* * PROJECT: ReactOS api tests * LICENSE: GPLv2+ - See COPYING in the top level directory * PURPOSE: Test for sprintf * PROGRAMMER: Thomas Faber */ #include #define WIN32_NO_STATUS #include #include #include #include #include #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wformat" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wnonnull" #endif static PVOID AllocateGuarded( SIZE_T SizeRequested) { NTSTATUS Status; SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); PVOID VirtualMemory = NULL; PCHAR StartOfBuffer; Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); if (!NT_SUCCESS(Status)) return NULL; Size -= PAGE_SIZE; if (Size) { Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { Size = 0; Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); return NULL; } } StartOfBuffer = VirtualMemory; StartOfBuffer += Size - SizeRequested; return StartOfBuffer; } static VOID FreeGuarded( PVOID Pointer) { NTSTATUS Status; PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); SIZE_T Size = 0; Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); } /* NOTE: This test is not only used for all the CRT apitests, but also for * user32's wsprintf. Make sure to test them all */ START_TEST(sprintf) { int Length; CHAR Buffer[128]; PCHAR String; /* basic parameter tests */ StartSeh() Length = sprintf(NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); StartSeh() Length = sprintf(NULL, ""); ok_int(Length, 0); #if defined(TEST_CRTDLL) || defined(TEST_USER32) EndSeh(STATUS_ACCESS_VIOLATION); #else EndSeh(STATUS_SUCCESS); #endif StartSeh() Length = sprintf(NULL, "Hello"); ok_int(Length, 5); #if defined(TEST_CRTDLL) || defined(TEST_USER32) EndSeh(STATUS_ACCESS_VIOLATION); #else EndSeh(STATUS_SUCCESS); #endif /* some basic formats */ Length = sprintf(Buffer, "abcde"); ok_str(Buffer, "abcde"); ok_int(Length, 5); Length = sprintf(Buffer, "%%"); ok_str(Buffer, "%"); ok_int(Length, 1); Length = sprintf(Buffer, "%"); ok_str(Buffer, ""); ok_int(Length, 0); Length = sprintf(Buffer, "%%%"); ok_str(Buffer, "%"); ok_int(Length, 1); Length = sprintf(Buffer, "%d", 8); ok_str(Buffer, "8"); ok_int(Length, 1); Length = sprintf(Buffer, "%s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); /* field width for %s */ Length = sprintf(Buffer, "%8s", "hello"); ok_str(Buffer, " hello"); ok_int(Length, 8); Length = sprintf(Buffer, "%4s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); Length = sprintf(Buffer, "%-8s", "hello"); ok_str(Buffer, "hello "); ok_int(Length, 8); Length = sprintf(Buffer, "%-5s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); Length = sprintf(Buffer, "%0s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); Length = sprintf(Buffer, "%-0s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); Length = sprintf(Buffer, "%*s", -8, "hello"); #ifdef TEST_USER32 ok_str(Buffer, "*s"); ok_int(Length, 2); #else ok_str(Buffer, "hello "); ok_int(Length, 8); #endif /* precision for %s */ Length = sprintf(Buffer, "%.s", "hello"); ok_str(Buffer, ""); ok_int(Length, 0); Length = sprintf(Buffer, "%.0s", "hello"); ok_str(Buffer, ""); ok_int(Length, 0); Length = sprintf(Buffer, "%.10s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); Length = sprintf(Buffer, "%.5s", "hello"); ok_str(Buffer, "hello"); ok_int(Length, 5); Length = sprintf(Buffer, "%.4s", "hello"); ok_str(Buffer, "hell"); ok_int(Length, 4); StartSeh() Length = sprintf(Buffer, "%.*s", -1, "hello"); #ifdef TEST_USER32 ok_str(Buffer, "*s"); ok_int(Length, 2); #else ok_str(Buffer, "hello"); ok_int(Length, 5); #endif EndSeh(STATUS_SUCCESS); String = AllocateGuarded(6); if (!String) { skip("Guarded allocation failure\n"); return; } strcpy(String, "hello"); StartSeh() Length = sprintf(Buffer, "%.8s", String); ok_str(Buffer, "hello"); ok_int(Length, 5); EndSeh(STATUS_SUCCESS); StartSeh() Length = sprintf(Buffer, "%.6s", String); ok_str(Buffer, "hello"); ok_int(Length, 5); EndSeh(STATUS_SUCCESS); StartSeh() Length = sprintf(Buffer, "%.5s", String); ok_str(Buffer, "hello"); ok_int(Length, 5); EndSeh(STATUS_SUCCESS); StartSeh() Length = sprintf(Buffer, "%.4s", String); ok_str(Buffer, "hell"); ok_int(Length, 4); EndSeh(STATUS_SUCCESS); String[5] = '!'; StartSeh() Length = sprintf(Buffer, "%.5s", String); ok_str(Buffer, "hello"); ok_int(Length, 5); #ifdef TEST_USER32 EndSeh(STATUS_ACCESS_VIOLATION); #else EndSeh(STATUS_SUCCESS); #endif StartSeh() Length = sprintf(Buffer, "%.6s", String); ok_str(Buffer, "hello!"); ok_int(Length, 6); #ifdef TEST_USER32 EndSeh(STATUS_ACCESS_VIOLATION); #else EndSeh(STATUS_SUCCESS); #endif StartSeh() Length = sprintf(Buffer, "%.*s", 5, String); #ifdef TEST_USER32 ok_str(Buffer, "*s"); ok_int(Length, 2); #else ok_str(Buffer, "hello"); ok_int(Length, 5); #endif EndSeh(STATUS_SUCCESS); StartSeh() Length = sprintf(Buffer, "%.*s", 6, String); #ifdef TEST_USER32 ok_str(Buffer, "*s"); ok_int(Length, 2); #else ok_str(Buffer, "hello!"); ok_int(Length, 6); #endif EndSeh(STATUS_SUCCESS); /* both field width and precision */ StartSeh() Length = sprintf(Buffer, "%8.5s", String); ok_str(Buffer, " hello"); ok_int(Length, 8); #ifdef TEST_USER32 EndSeh(STATUS_ACCESS_VIOLATION); #else EndSeh(STATUS_SUCCESS); #endif StartSeh() Length = sprintf(Buffer, "%-*.6s", -8, String); #ifdef TEST_USER32 ok_str(Buffer, "*.6s"); ok_int(Length, 4); #else ok_str(Buffer, "hello! "); ok_int(Length, 8); #endif EndSeh(STATUS_SUCCESS); StartSeh() Length = sprintf(Buffer, "%*.*s", -8, 6, String); #ifdef TEST_USER32 ok_str(Buffer, "*.*s"); ok_int(Length, 4); #else ok_str(Buffer, "hello! "); ok_int(Length, 8); #endif EndSeh(STATUS_SUCCESS); FreeGuarded(String); }