kernelbase: Don't allow the full Unicode character range in StrToInt* functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Alexandre Julliard 2020-03-10 12:22:14 +01:00
parent ef95e4a8b9
commit 0eec0eb7e0
2 changed files with 76 additions and 38 deletions

View File

@ -849,8 +849,7 @@ BOOL WINAPI StrToInt64ExA(const char *str, DWORD flags, LONGLONG *ret)
WARN("Unknown flags %#x\n", flags);
/* Skip leading space, '+', '-' */
while (*str == ' ' || (*str >= '\t' && *str <= '\r'))
str = CharNextA(str);
while (*str == ' ' || *str == '\t' || *str == '\n') str++;
if (*str == '-')
{
@ -913,8 +912,7 @@ BOOL WINAPI StrToInt64ExW(const WCHAR *str, DWORD flags, LONGLONG *ret)
WARN("Unknown flags %#x.\n", flags);
/* Skip leading space, '+', '-' */
while (iswspace(*str))
str++;
while (*str == ' ' || *str == '\t' || *str == '\n') str++;
if (*str == '-')
{
@ -929,10 +927,10 @@ BOOL WINAPI StrToInt64ExW(const WCHAR *str, DWORD flags, LONGLONG *ret)
/* Read hex number */
str += 2;
if (!iswxdigit(*str))
if (!isxdigit(*str))
return FALSE;
while (iswxdigit(*str))
while (isxdigit(*str))
{
value *= 16;
if (*str >= '0' && *str <= '9')
@ -949,10 +947,10 @@ BOOL WINAPI StrToInt64ExW(const WCHAR *str, DWORD flags, LONGLONG *ret)
}
/* Read decimal number */
if (!iswdigit(*str))
if (*str < '0' || *str > '9')
return FALSE;
while (iswdigit(*str))
while (*str >= '0' && *str <= '9')
{
value *= 10;
value += (*str - '0');
@ -996,7 +994,7 @@ int WINAPI StrToIntA(const char *str)
if (!str)
return 0;
if (*str == '-' || isdigit(*str))
if (*str == '-' || (*str >= '0' && *str <= '9'))
StrToIntExA(str, 0, &value);
return value;
@ -1011,7 +1009,7 @@ int WINAPI StrToIntW(const WCHAR *str)
if (!str)
return 0;
if (*str == '-' || iswdigit(*str))
if (*str == '-' || (*str >= '0' && *str <= '9'))
StrToIntExW(str, 0, &value);
return value;
}
@ -1312,11 +1310,11 @@ int WINAPI StrCmpLogicalW(const WCHAR *str, const WCHAR *comp)
{
if (!*comp)
return 1;
else if (iswdigit(*str))
else if (*str >= '0' && *str <= '9')
{
int str_value, comp_value;
if (!iswdigit(*comp))
if (*comp < '0' || *comp > '9')
return -1;
/* Compare the numbers */
@ -1329,12 +1327,10 @@ int WINAPI StrCmpLogicalW(const WCHAR *str, const WCHAR *comp)
return 1;
/* Skip */
while (iswdigit(*str))
str++;
while (iswdigit(*comp))
comp++;
while (*str >= '0' && *str <= '9') str++;
while (*comp >= '0' && *comp <= '9') comp++;
}
else if (iswdigit(*comp))
else if (*comp >= '0' && *comp <= '9')
return 1;
else
{

View File

@ -76,6 +76,7 @@ typedef struct tagStrToIntResult
int str_to_int;
LONGLONG str_to_int64_ex;
LONGLONG str_to_int64_hex;
BOOL failure;
} StrToIntResult;
static const StrToIntResult StrToInt_results[] = {
@ -89,11 +90,12 @@ static const StrToIntResult StrToInt_results[] = {
{ "0x2bdc546291f4b1", 0, 0, ((LONGLONG)0x2bdc54 << 32) | 0x6291f4b1 },
{ "+0x44f4", 0, 0, 0x44f4 },
{ "-0x44fd", 0, 0, 0x44fd },
{ "+ 88987", 0, 0, 0 },
{ "- 55", 0, 0, 0 },
{ "- 0", 0, 0, 0 },
{ "+ 0x44f4", 0, 0, 0 },
{ "--0x44fd", 0, 0, 0 },
{ "+ 88987", 0, 0, 0, TRUE },
{ "- 55", 0, 0, 0, TRUE },
{ "- 0", 0, 0, 0, TRUE },
{ "+ 0x44f4", 0, 0, 0, TRUE },
{ "--0x44fd", 0, 0, 0, TRUE },
{ " 1999", 0, 1999, 1999 },
{ " +88987", 0, 88987, 88987 },
{ " 012", 0, 12, 12 },
@ -101,6 +103,10 @@ static const StrToIntResult StrToInt_results[] = {
{ " 0x44ff", 0, 0, 0x44ff },
{ " +0x44f4", 0, 0, 0x44f4 },
{ " -0x44fd", 0, 0, 0x44fd },
{ "\t\n +3", 0, 3, 3 },
{ "\v+4", 0, 0, 0, TRUE },
{ "\f+5", 0, 0, 0, TRUE },
{ "\r+6", 0, 0, 0, TRUE },
{ NULL, 0, 0, 0 }
};
@ -488,8 +494,10 @@ static void test_StrToIntExA(void)
{
return_val = -1;
bRet = StrToIntExA(result->string,0,&return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n",
result->string, return_val);
@ -501,8 +509,10 @@ static void test_StrToIntExA(void)
{
return_val = -1;
bRet = StrToIntExA(result->string,STIF_SUPPORT_HEX,&return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n",
result->string, return_val);
@ -522,8 +532,10 @@ static void test_StrToIntExW(void)
return_val = -1;
MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = StrToIntExW(szBuff, 0, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n",
result->string, return_val);
@ -536,13 +548,23 @@ static void test_StrToIntExW(void)
return_val = -1;
MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = StrToIntExW(szBuff, STIF_SUPPORT_HEX, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n",
result->string, return_val);
result++;
}
return_val = -1;
bRet = StrToIntExW(L"\x0661\x0662", 0, &return_val);
ok( !bRet, "Returned %d for Unicode digits\n", return_val );
bRet = StrToIntExW(L"\x07c3\x07c4", 0, &return_val);
ok( !bRet, "Returned %d for Unicode digits\n", return_val );
bRet = StrToIntExW(L"\xa0-2", 0, &return_val);
ok( !bRet, "Returned %d for Unicode space\n", return_val );
}
static void test_StrToInt64ExA(void)
@ -561,8 +583,11 @@ static void test_StrToInt64ExA(void)
{
return_val = -1;
bRet = pStrToInt64ExA(result->string,0,&return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %s instead of failure for '%s'\n",
wine_dbgstr_longlong(return_val), result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n",
result->string, wine_dbgstr_longlong(return_val));
@ -574,8 +599,11 @@ static void test_StrToInt64ExA(void)
{
return_val = -1;
bRet = pStrToInt64ExA(result->string,STIF_SUPPORT_HEX,&return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %s instead of failure for '%s'\n",
wine_dbgstr_longlong(return_val), result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n",
result->string, wine_dbgstr_longlong(return_val));
@ -601,8 +629,11 @@ static void test_StrToInt64ExW(void)
return_val = -1;
MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = pStrToInt64ExW(szBuff, 0, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %s instead of failure for '%s'\n",
wine_dbgstr_longlong(return_val), result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n",
result->string, wine_dbgstr_longlong(return_val));
@ -615,13 +646,24 @@ static void test_StrToInt64ExW(void)
return_val = -1;
MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = pStrToInt64ExW(szBuff, STIF_SUPPORT_HEX, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
if (result->failure)
ok(!bRet, "Got %s instead of failure for '%s'\n",
wine_dbgstr_longlong(return_val), result->string);
else
ok(bRet, "Failed for '%s'\n", result->string);
if (bRet)
ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n",
result->string, wine_dbgstr_longlong(return_val));
result++;
}
return_val = -1;
bRet = pStrToInt64ExW(L"\x0661\x0662", 0, &return_val);
ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) );
bRet = pStrToInt64ExW(L"\x07c3\x07c4", 0, &return_val);
ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) );
bRet = pStrToInt64ExW(L"\xa0-2", 0, &return_val);
ok( !bRet, "Returned %s for Unicode space\n", wine_dbgstr_longlong(return_val) );
}
static void test_StrDupA(void)