Commit 9df3f06c authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

msvcrt: Use macro for parameters validation itoa_s (and update the tests as well).

parent be01cdb6
......@@ -63,6 +63,7 @@ static char **p_sys_errlist;
static char** (__cdecl *p__sys_errlist)(void);
static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
static void* (WINAPI *pEncodePointer)(void *);
......@@ -282,6 +283,108 @@ static void test__strtoi64(void)
ok(errno == 0xdeadbeef, "errno = %x\n", errno);
}
static void test__itoa_s(void)
{
errno_t ret;
char buffer[33];
if (!p_itoa_s)
{
win_skip("Skipping _itoa_s tests\n");
return;
}
if(!p_set_invalid_parameter_handler) {
win_skip("_set_invalid_parameter_handler not found\n");
return;
}
/* _itoa_s (on msvcr90) doesn't set errno (in case of errors) while msvcrt does
* as we always set errno in our msvcrt implementation, don't test here that errno
* isn't changed
*/
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(0, NULL, 0, 0);
ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
CHECK_CALLED(invalid_parameter_handler);
memset(buffer, 'X', sizeof(buffer));
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(0, buffer, 0, 0);
ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
CHECK_CALLED(invalid_parameter_handler);
memset(buffer, 'X', sizeof(buffer));
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
CHECK_CALLED(invalid_parameter_handler);
memset(buffer, 'X', sizeof(buffer));
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
CHECK_CALLED(invalid_parameter_handler);
memset(buffer, 'X', sizeof(buffer));
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(12345678, buffer, 4, 10);
ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
ok(!memcmp(buffer, "\000765", 4),
"Expected the output buffer to be null terminated with truncated output\n");
CHECK_CALLED(invalid_parameter_handler);
memset(buffer, 'X', sizeof(buffer));
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(12345678, buffer, 8, 10);
ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
ok(!memcmp(buffer, "\0007654321", 8),
"Expected the output buffer to be null terminated with truncated output\n");
CHECK_CALLED(invalid_parameter_handler);
memset(buffer, 'X', sizeof(buffer));
SET_EXPECT(invalid_parameter_handler);
ret = p_itoa_s(-12345678, buffer, 9, 10);
ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
ok(!memcmp(buffer, "\00087654321", 9),
"Expected the output buffer to be null terminated with truncated output\n");
CHECK_CALLED(invalid_parameter_handler);
ret = p_itoa_s(12345678, buffer, 9, 10);
ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
ok(!strcmp(buffer, "12345678"),
"Expected output buffer string to be \"12345678\", got \"%s\"\n",
buffer);
ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
ok(!strcmp(buffer, "1010101010101010"),
"Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
buffer);
ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
ok(!strcmp(buffer, "nell"),
"Expected output buffer string to be \"nell\", got \"%s\"\n",
buffer);
ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
ok(!strcmp(buffer, "hag"),
"Expected output buffer string to be \"hag\", got \"%s\"\n",
buffer);
ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
ok(!strcmp(buffer, "-12345678"),
"Expected output buffer string to be \"-12345678\", got \"%s\"\n",
buffer);
}
/* ########## */
START_TEST(msvcr90)
......@@ -311,6 +414,7 @@ START_TEST(msvcr90)
p__sys_errlist = (void *) GetProcAddress(hcrt, "__sys_errlist");
p_strtoi64 = (void *) GetProcAddress(hcrt, "_strtoi64");
p_strtoui64 = (void *) GetProcAddress(hcrt, "_strtoui64");
p_itoa_s = (void *)GetProcAddress(hcrt, "_itoa_s");
hkernel32 = GetModuleHandleA("kernel32.dll");
pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
......@@ -319,4 +423,5 @@ START_TEST(msvcr90)
test__encode_pointer();
test_error_messages();
test__strtoi64();
test__itoa_s();
}
......@@ -680,7 +680,8 @@ int CDECL _itoa_s(int value, char *str, MSVCRT_size_t size, int radix)
char buffer[33], *pos;
size_t len;
if (!str || !size || radix < 2 || radix > 36)
if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
!MSVCRT_CHECK_PMT(radix >= 2) || !MSVCRT_CHECK_PMT(radix <= 36))
{
if (str && size)
str[0] = '\0';
......@@ -737,6 +738,7 @@ int CDECL _itoa_s(int value, char *str, MSVCRT_size_t size, int radix)
*p++ = *pos--;
str[0] = '\0';
MSVCRT_INVALID_PMT("str[size] is too small");
*MSVCRT__errno() = MSVCRT_ERANGE;
return MSVCRT_ERANGE;
}
......@@ -831,8 +833,8 @@ int CDECL MSVCRT__ui64toa_s(unsigned __int64 value, char *str,
char buffer[65], *pos;
int digit;
if(!str || radix<2 || radix>36) {
MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
if (!MSVCRT_CHECK_PMT(str != NULL) || !MSVCRT_CHECK_PMT(size > 0) ||
!MSVCRT_CHECK_PMT(radix>=2) || !MSVCRT_CHECK_PMT(radix<=36)) {
*MSVCRT__errno() = MSVCRT_EINVAL;
return MSVCRT_EINVAL;
}
......@@ -851,7 +853,7 @@ int CDECL MSVCRT__ui64toa_s(unsigned __int64 value, char *str,
}while(value != 0);
if(buffer-pos+65 > size) {
MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
MSVCRT_INVALID_PMT("str[size] is too small");
*MSVCRT__errno() = MSVCRT_EINVAL;
return MSVCRT_EINVAL;
}
......
......@@ -43,6 +43,13 @@ static char *buf_to_string(const unsigned char *bin, int len, int nr)
return buf[nr];
}
static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
const wchar_t *function, const wchar_t *file,
unsigned line, uintptr_t arg)
{
/* we just ignore handler calls */
}
#define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
#define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, "Binary buffer mismatch - expected %s, got %s\n", buf_to_string((unsigned char *)value, len, 1), buf_to_string((buf), len, 0)); }
......@@ -66,6 +73,7 @@ static errno_t (__cdecl *p_strlwr_s)(char*,size_t);
static errno_t (__cdecl *p_ultoa_s)(__msvcrt_ulong,char*,size_t,int);
static int *p__mb_cur_max;
static unsigned char *p_mbctype;
static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
#define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
......@@ -1293,6 +1301,10 @@ static void test__itoa_s(void)
return;
}
if (p_set_invalid_parameter_handler)
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
"Invalid parameter handler was already set\n");
errno = EBADF;
ret = p_itoa_s(0, NULL, 0, 0);
ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
......@@ -1372,6 +1384,9 @@ static void test__itoa_s(void)
ok(!strcmp(buffer, "-12345678"),
"Expected output buffer string to be \"-12345678\", got \"%s\"\n",
buffer);
if (p_set_invalid_parameter_handler)
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
"Cannot reset invalid parameter handler\n");
}
static void test__strlwr_s(void)
......@@ -1705,6 +1720,7 @@ START_TEST(string)
p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s");
p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s");
p_ultoa_s = (void *)GetProcAddress(hMsvcrt, "_ultoa_s");
p_set_invalid_parameter_handler = (void *) GetProcAddress(hMsvcrt, "_set_invalid_parameter_handler");
/* MSVCRT memcpy behaves like memmove for overlapping moves,
MFC42 CString::Insert seems to rely on that behaviour */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment