[CRT_APITEST]
[reactos.git] / rostests / apitests / crt / mbstowcs_s.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for mbstowcs_s
5 */
6
7 #define WIN32_NO_STATUS
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <wine/test.h>
11 #include <specstrings.h>
12
13 #define ok_errno(x) ok_hex(errno, (x))
14
15 errno_t
16 mbstowcs_s(
17 size_t *returnval,
18 wchar_t *widechar,
19 size_t charoutct,
20 const char *multibyte,
21 size_t count);
22
23 void
24 _invalid_parameter(
25 const wchar_t * expression,
26 const wchar_t * function,
27 const wchar_t * file,
28 unsigned int line,
29 uintptr_t pReserved);
30
31 void
32 _invalid_parameterA(
33 const char * expression,
34 const char * function,
35 const char * file,
36 unsigned int line,
37 uintptr_t pReserved)
38 {
39 // call _invalid_parameter
40 }
41
42 #define MSVCRT_INVALID_PMT(x) _invalid_parameterA(#x, __FUNCTION__, __FILE__, __LINE__, 0)
43 #define MSVCRT_CHECK_PMT(x) ((x) || (MSVCRT_INVALID_PMT(x),0))
44
45 #define _mbsnlen strnlen
46
47 errno_t
48 mbstowcs_s(
49 _Out_opt_ size_t *pReturnValue,
50 _Out_ wchar_t *pwcstr,
51 _In_ size_t sizeInWords,
52 _In_ const char *pmbstr,
53 _In_ size_t count)
54 {
55 size_t cchMax, cwcWritten;
56 errno_t retval = 0;
57
58 if (!MSVCRT_CHECK_PMT( ((sizeInWords != 0) && (pwcstr != 0)) ||
59 ((sizeInWords == 0) && (pwcstr == 0)) ))
60 {
61 _set_errno(EINVAL);
62 return EINVAL;
63 }
64
65 /* Check if we have a return value pointer */
66 if (pReturnValue)
67 {
68 /* Default to 0 bytes written */
69 *pReturnValue = 0;
70 }
71
72 if (!MSVCRT_CHECK_PMT((count == 0) || (pmbstr != 0)))
73 {
74 _set_errno(EINVAL);
75 return EINVAL;
76 }
77
78 /* Check if there is anything to do */
79 if ((pwcstr == 0) && (pmbstr == 0))
80 {
81 _set_errno(EINVAL);
82 return EINVAL;
83 }
84
85 /* Check if we have a source string */
86 if (pmbstr)
87 {
88 /* Check if we also have a wchar buffer */
89 if (pwcstr)
90 {
91 /* Calculate the maximum the we can write */
92 cchMax = (count < sizeInWords) ? count + 1 : sizeInWords;
93
94 /* Now do the conversion */
95 cwcWritten = mbstowcs(pwcstr, pmbstr, cchMax);
96
97 /* Check if the buffer was not zero terminated */
98 if (cwcWritten == cchMax)
99 {
100 /* Check if we reached the max size of the dest buffer */
101 if (cwcWritten == sizeInWords)
102 {
103 /* Does the caller allow this? */
104 if (count != _TRUNCATE)
105 {
106 /* Not allowed, truncate to 0 length */
107 pwcstr[0] = L'\0';
108
109 /* Return error */
110 _set_errno(ERANGE);
111 return ERANGE;
112 }
113
114 /* Inform the caller about truncation */
115 retval = STRUNCATE;
116 }
117
118 /* zero teminate the buffer */
119 pwcstr[cwcWritten - 1] = L'\0';
120 }
121 else
122 {
123 /* The buffer is zero terminated, count the terminating char */
124 cwcWritten++;
125 }
126 }
127 else
128 {
129 /* Get the length of the string, plus 0 terminator */
130 cwcWritten = _mbsnlen(pmbstr, count) + 1;
131 }
132 }
133 else
134 {
135 cwcWritten = count + 1;
136 }
137
138 /* Check if we have a return value pointer */
139 if (pReturnValue)
140 {
141 /* Default to 0 bytes written */
142 *pReturnValue = cwcWritten;
143 }
144
145 return retval;
146 }
147
148
149
150 wchar_t g_expression[64];
151 wchar_t g_function[64];
152 wchar_t g_file[128];
153 unsigned int g_line;
154 uintptr_t g_pReserved;
155
156 void
157 _test_invalid_parameter(
158 const wchar_t * expression,
159 const wchar_t * function,
160 const wchar_t * file,
161 unsigned int line,
162 uintptr_t pReserved)
163 {
164 wcsncpy(g_expression, expression, sizeof(g_expression) / sizeof(wchar_t));
165 wcsncpy(g_function, function, sizeof(g_function) / sizeof(wchar_t));
166 wcsncpy(g_file, file, sizeof(g_file) / sizeof(wchar_t));
167 g_line = line;
168 g_pReserved = pReserved;
169 }
170
171 START_TEST(mbstowcs_s)
172 {
173 // _set_invalid_parameter_handler(_test_invalid_parameter);
174
175 errno_t ret;
176 size_t returnval;
177 wchar_t widechar[10];
178 #if 1
179 _set_errno(0);
180 returnval = 0xf00bac;
181 widechar[5] = 0xFF;
182 ret = mbstowcs_s(&returnval, widechar, 6, "hallo", 5);
183 ok_long(ret, 0);
184 ok_size_t(returnval, 6);
185 ok_char(widechar[5], 0);
186 ok_wstr(widechar, L"hallo");
187 ok_errno(0);
188
189 _set_errno(0);
190 returnval = 0xf00bac;
191 widechar[0] = 0xFF;
192 ret = mbstowcs_s(&returnval, widechar, 1, "", 0);
193 ok_long(ret, 0);
194 ok_size_t(returnval, 1);
195 ok_char(widechar[0], 0);
196 ok_errno(0);
197
198 _set_errno(0);
199 returnval = 0xf00bac;
200 widechar[0] = 0xFF;
201 widechar[1] = 0xFF;
202 widechar[2] = 0xFF;
203 widechar[3] = 0xFF;
204 widechar[4] = 0xFF;
205 widechar[5] = 0xFF;
206 ret = mbstowcs_s(&returnval, widechar, 5, "hallo", 5);
207 ok_long(ret, ERANGE);
208 ok_size_t(returnval, 0);
209 ok_char(widechar[5], 0xFF);
210 ok_char(widechar[4], L'o');
211 ok_char(widechar[3], L'l');
212 ok_char(widechar[2], L'l');
213 ok_char(widechar[1], L'a');
214 ok_char(widechar[0], 0);
215 ok_errno(ERANGE);
216
217 _set_errno(0);
218 returnval = 0xf00bac;
219 widechar[0] = 0xFF;
220 widechar[1] = 0xFF;
221 widechar[2] = 0xFF;
222 widechar[3] = 0xFF;
223 widechar[4] = 0xFF;
224 widechar[5] = 0xFF;
225 ret = mbstowcs_s(&returnval, widechar, 3, "hallo", 5);
226 ok_long(ret, ERANGE);
227 ok_size_t(returnval, 0);
228 ok_char(widechar[5], 0xFF);
229 ok_char(widechar[4], 0xFF);
230 ok_char(widechar[3], 0xFF);
231 ok_char(widechar[2], L'l');
232 ok_char(widechar[1], L'a');
233 ok_char(widechar[0], 0);
234 ok_errno(ERANGE);
235
236 _set_errno(0);
237 ret = mbstowcs_s(0, 0, 0, 0, 0);
238 ok_long(ret, EINVAL);
239 ok_errno(EINVAL);
240
241 _set_errno(0);
242 returnval = 0xf00bac;
243 ret = mbstowcs_s(&returnval, 0, 0, 0, 0);
244 ok_long(ret, EINVAL);
245 ok_size_t(returnval, 0);
246 ok_errno(EINVAL);
247
248 _set_errno(0);
249 widechar[0] = L'x';
250 ret = mbstowcs_s(0, widechar, 0, 0, 0);
251 ok_long(ret, EINVAL);
252 ok_char(widechar[0], L'x');
253 ok_errno(EINVAL);
254
255 _set_errno(0);
256 ret = mbstowcs_s(0, widechar, 10, "hallo", 5);
257 ok_long(ret, 0);
258 ok_errno(0);
259
260 _set_errno(0);
261 ret = mbstowcs_s(0, widechar, 0, "hallo", 5);
262 ok_long(ret, EINVAL);
263 ok_errno(EINVAL);
264
265 _set_errno(0);
266 returnval = 0xf00bac;
267 ret = mbstowcs_s(&returnval, 0, 10, "hallo", 5);
268 ok_long(ret, EINVAL);
269 ok_size_t(returnval, 0xf00bac);
270 ok_errno(EINVAL);
271
272 _set_errno(0);
273 returnval = 0xf00bac;
274 ret = mbstowcs_s(&returnval, 0, 0, "hallo", 5);
275 ok_long(ret, 0);
276 ok_size_t(returnval, 6);
277 ok_errno(0);
278
279 _set_errno(0);
280 returnval = 0xf00bac;
281 ret = mbstowcs_s(&returnval, widechar, 10, 0, 5);
282 ok_long(ret, EINVAL);
283 ok_size_t(returnval, 0);
284 ok_errno(EINVAL);
285
286 _set_errno(0);
287 returnval = 0xf00bac;
288 ret = mbstowcs_s(&returnval, widechar, 10, "hallo", 0);
289 ok_long(ret, 0);
290 ok_size_t(returnval, 1);
291 ok_errno(0);
292 #endif
293 _set_errno(0);
294 returnval = 0xf00bac;
295 widechar[0] = 0xABCD;
296 widechar[1] = 0xABCD;
297 widechar[2] = 0xABCD;
298 widechar[3] = 0xABCD;
299 widechar[4] = 0xABCD;
300 widechar[5] = 0xABCD;
301 ret = mbstowcs_s(&returnval, widechar, 10, "hallo", 2);
302 ok_long(ret, 0);
303 ok_size_t(returnval, 3);
304 ok_char(widechar[5], 0xABCD);
305 ok_char(widechar[4], 0xABCD);
306 ok_char(widechar[3], 0xABCD);
307 ok_char(widechar[2], 0);
308 ok_char(widechar[1], L'a');
309 ok_char(widechar[0], L'h');
310 ok_errno(0);
311 #if 1
312 _set_errno(0);
313 returnval = 0xf00bac;
314 ret = mbstowcs_s(&returnval, widechar, 10, 0, 0);
315 ok_long(ret, 0);
316 ok_size_t(returnval, 1);
317 ok_errno(0);
318
319 _set_errno(0);
320 returnval = 0xf00bac;
321 ret = mbstowcs_s(&returnval, widechar, 10, "hallo", 7);
322 ok_long(ret, 0);
323 ok_size_t(returnval, 6);
324 ok_errno(0);
325
326 _set_errno(0);
327 returnval = 0xf00bac;
328 ret = mbstowcs_s(&returnval, 0, 0, "hallo", 7);
329 ok_long(ret, 0);
330 ok_size_t(returnval, 6);
331 ok_errno(0);
332
333 _set_errno(0);
334 returnval = 0xf00bac;
335 widechar[0] = 0xABCD;
336 widechar[1] = 0xABCD;
337 widechar[2] = 0xABCD;
338 widechar[3] = 0xABCD;
339 widechar[4] = 0xABCD;
340 widechar[5] = 0xABCD;
341 ret = mbstowcs_s(&returnval, widechar, 5, "hallo", _TRUNCATE);
342 ok_long(ret, STRUNCATE);
343 ok_size_t(returnval, 5);
344 ok_char(widechar[5], 0xABCD);
345 ok_char(widechar[4], 0);
346 ok_char(widechar[3], L'l');
347 ok_char(widechar[2], L'l');
348 ok_char(widechar[1], L'a');
349 ok_char(widechar[0], L'h');
350 ok_errno(0);
351
352 _set_errno(0);
353 returnval = 0xf00bac;
354 ret = mbstowcs_s(&returnval, widechar, 10, "hallo", -1);
355 ok_long(ret, 0);
356 ok_size_t(returnval, 6);
357 ok_errno(0);
358 #endif
359
360 }