mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 21:57:18 +00:00
msvcrt: Correctly handle the error cases in strtol and strtoul.
This commit is contained in:
parent
b42243e8e7
commit
9eca2f81dc
|
@ -41,6 +41,9 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
||||
#define MSVCRT_LONG_MAX 0x7fffffffL
|
||||
#define MSVCRT_ULONG_MAX 0xffffffffUL
|
||||
|
||||
typedef unsigned short MSVCRT_wchar_t;
|
||||
typedef unsigned short MSVCRT_wint_t;
|
||||
typedef unsigned short MSVCRT_wctype_t;
|
||||
|
|
|
@ -767,8 +767,8 @@
|
|||
@ cdecl strstr(str str) ntdll.strstr
|
||||
@ cdecl strtod(str ptr) MSVCRT_strtod
|
||||
@ cdecl strtok(str str) MSVCRT_strtok
|
||||
@ cdecl strtol(str ptr long) ntdll.strtol
|
||||
@ cdecl strtoul(str ptr long) ntdll.strtoul
|
||||
@ cdecl strtol(str ptr long) MSVCRT_strtol
|
||||
@ cdecl strtoul(str ptr long) MSVCRT_strtoul
|
||||
@ cdecl strxfrm(ptr str long) MSVCRT_strxfrm
|
||||
@ varargs swprintf(ptr wstr) MSVCRT_swprintf
|
||||
@ varargs swscanf(wstr wstr) MSVCRT_swscanf
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "msvcrt.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -250,3 +251,66 @@ int CDECL __STRINGTOLD( MSVCRT__LDOUBLE *value, char **endptr, const char *str,
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* strtol (MSVCRT.@)
|
||||
*/
|
||||
long int MSVCRT_strtol(const char* nptr, char** end, int base)
|
||||
{
|
||||
/* wrapper to forward libc error code to msvcrt's error codes */
|
||||
long ret;
|
||||
|
||||
errno = 0;
|
||||
ret = strtol(nptr, end, base);
|
||||
switch (errno)
|
||||
{
|
||||
case ERANGE: *MSVCRT__errno() = MSVCRT_ERANGE; break;
|
||||
case EINVAL: *MSVCRT__errno() = MSVCRT_EINVAL; break;
|
||||
default:
|
||||
/* cope with the fact that we may use 64bit long integers on libc
|
||||
* while msvcrt always uses 32bit long integers
|
||||
*/
|
||||
if (ret > MSVCRT_LONG_MAX)
|
||||
{
|
||||
ret = MSVCRT_LONG_MAX;
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
}
|
||||
else if (ret < -MSVCRT_LONG_MAX - 1)
|
||||
{
|
||||
ret = -MSVCRT_LONG_MAX - 1;
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* strtoul (MSVCRT.@)
|
||||
*/
|
||||
unsigned long int MSVCRT_strtoul(const char* nptr, char** end, int base)
|
||||
{
|
||||
/* wrapper to forward libc error code to msvcrt's error codes */
|
||||
unsigned long ret;
|
||||
|
||||
errno = 0;
|
||||
ret = strtoul(nptr, end, base);
|
||||
switch (errno)
|
||||
{
|
||||
case ERANGE: *MSVCRT__errno() = MSVCRT_ERANGE; break;
|
||||
case EINVAL: *MSVCRT__errno() = MSVCRT_EINVAL; break;
|
||||
default:
|
||||
/* cope with the fact that we may use 64bit long integers on libc
|
||||
* while msvcrt always uses 32bit long integers
|
||||
*/
|
||||
if (ret > MSVCRT_ULONG_MAX)
|
||||
{
|
||||
ret = MSVCRT_ULONG_MAX;
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -663,6 +663,45 @@ static void test_strtok(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_strtol(void)
|
||||
{
|
||||
char* e;
|
||||
long l;
|
||||
unsigned long ul;
|
||||
|
||||
/* errno is only set in case of error, so reset errno to EBADF to check for errno modification */
|
||||
errno = EBADF;
|
||||
l = strtol("-1234", &e, 0);
|
||||
ok(l==-1234, "wrong value %ld\n", l);
|
||||
ok(errno == EBADF, "wrong errno %d\n", errno);
|
||||
errno = EBADF;
|
||||
ul = strtoul("1234", &e, 0);
|
||||
ok(ul==1234, "wrong value %lu\n", ul);
|
||||
ok(errno == EBADF, "wrong errno %d\n", errno);
|
||||
|
||||
errno = EBADF;
|
||||
l = strtol("2147483647L", &e, 0);
|
||||
ok(l==2147483647, "wrong value %ld\n", l);
|
||||
ok(errno == EBADF, "wrong errno %d\n", errno);
|
||||
errno = EBADF;
|
||||
l = strtol("-2147483648L", &e, 0);
|
||||
ok(l==-2147483647L - 1, "wrong value %ld\n", l);
|
||||
ok(errno == EBADF, "wrong errno %d\n", errno);
|
||||
errno = EBADF;
|
||||
ul = strtoul("4294967295UL", &e, 0);
|
||||
ok(ul==4294967295ul, "wrong value %lu\n", ul);
|
||||
ok(errno == EBADF, "wrong errno %d\n", errno);
|
||||
|
||||
errno = 0;
|
||||
l = strtol("9223372036854775807L", &e, 0);
|
||||
ok(l==2147483647, "wrong value %ld\n", l);
|
||||
ok(errno == ERANGE, "wrong errno %d\n", errno);
|
||||
errno = 0;
|
||||
ul = strtoul("9223372036854775807L", &e, 0);
|
||||
ok(ul==4294967295ul, "wrong value %lu\n", ul);
|
||||
ok(errno == ERANGE, "wrong errno %d\n", errno);
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
char mem[100];
|
||||
|
@ -706,4 +745,5 @@ START_TEST(string)
|
|||
test_mbcjisjms();
|
||||
test_strtok();
|
||||
test_wcscpy_s();
|
||||
test_strtol();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue