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