ntdll: Don't handle the full Unicode character range in isw* functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-03-10 20:54:50 +01:00
parent 1986328543
commit 650c8e1434
2 changed files with 159 additions and 20 deletions

View File

@ -74,6 +74,13 @@ static int (__cdecl *p_strnicmp)(LPCSTR,LPCSTR,size_t);
static int (WINAPIV *psscanf)(const char *, const char *, ...);
static int (__cdecl *piswctype)(WCHAR,unsigned short);
static int (__cdecl *piswalpha)(WCHAR);
static int (__cdecl *piswdigit)(WCHAR);
static int (__cdecl *piswlower)(WCHAR);
static int (__cdecl *piswspace)(WCHAR);
static int (__cdecl *piswxdigit)(WCHAR);
static void InitFunctionPtrs(void)
{
hntdll = LoadLibraryA("ntdll.dll");
@ -116,6 +123,12 @@ static void InitFunctionPtrs(void)
X(toupper);
X(_strnicmp);
X(sscanf);
X(iswctype);
X(iswalpha);
X(iswdigit);
X(iswlower);
X(iswspace);
X(iswxdigit);
#undef X
}
@ -957,7 +970,11 @@ static void test_wtol(void)
"(test %d): call failed: _wtol(\"%s\") has result %d, expected: %d\n",
test_num, str2long[test_num].str, result, str2long[test_num].value);
pRtlFreeUnicodeString(&uni);
} /* for */
}
result = p_wtol( L"\t\xa0\n 12" );
ok( result == 12, "got %d\n", result );
result = p_wtol( L"\x3000 12" );
ok( result == 0, "got %d\n", result );
}
@ -1130,6 +1147,10 @@ static void test_wtoi64(void)
wine_dbgstr_longlong(str2longlong[test_num].value));
pRtlFreeUnicodeString(&uni);
}
result = p_wtoi64( L"\t\xa0\n 12" );
ok( result == 12, "got %s\n", wine_dbgstr_longlong(result) );
result = p_wtoi64( L"\x2002\x2003 12" );
ok( result == 0, "got %s\n", wine_dbgstr_longlong(result) );
}
static void test_wcschr(void)
@ -1569,6 +1590,74 @@ static void test_sscanf(void)
ok(d == 0.0, "d = %lf\n", f);
}
static const unsigned short wctypes[256] =
{
/* 00 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0068, 0x0028, 0x0028, 0x0028, 0x0028, 0x0020, 0x0020,
/* 10 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
/* 20 */
0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* 30 */
0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084,
0x0084, 0x0084, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* 40 */
0x0010, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0101,
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
/* 50 */
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
0x0101, 0x0101, 0x0101, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* 60 */
0x0010, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0102,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
/* 70 */
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0102, 0x0102, 0x0102, 0x0010, 0x0010, 0x0010, 0x0010, 0x0020,
/* 80 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
/* 90 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
/* a0 */
0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* b0 */
0x0010, 0x0010, 0x0014, 0x0014, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0014, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* c0 */
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
/* d0 */
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0010,
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0102,
/* e0 */
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
/* f0 */
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0010,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102
};
static void test_wctype(void)
{
int i;
for (i = 0; i < 65536; i++)
{
unsigned short type = (i < 256 ? wctypes[i] : 0);
ok( piswctype( i, 0xffff ) == type, "%u: wrong type %x\n", i, piswctype( i, 0xffff ));
ok( piswalpha( i ) == (type & (C1_ALPHA|C1_LOWER|C1_UPPER)), "%u: wrong iswalpha\n", i );
ok( piswdigit( i ) == (type & C1_DIGIT), "%u: wrong iswdigit\n", i );
ok( piswlower( i ) == (type & C1_LOWER), "%u: wrong iswlower\n", i );
ok( piswspace( i ) == (type & C1_SPACE), "%u: wrong iswspace\n", i );
ok( piswxdigit( i ) == (type & C1_XDIGIT), "%u: wrong iswxdigit\n", i );
}
}
START_TEST(string)
{
InitFunctionPtrs();
@ -1595,4 +1684,5 @@ START_TEST(string)
test__strnicmp();
test_wcsicmp();
test_sscanf();
test_wctype();
}

View File

@ -33,6 +33,59 @@
#include "winternl.h"
#include "wine/unicode.h"
static const unsigned short wctypes[256] =
{
/* 00 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0068, 0x0028, 0x0028, 0x0028, 0x0028, 0x0020, 0x0020,
/* 10 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
/* 20 */
0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* 30 */
0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084,
0x0084, 0x0084, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* 40 */
0x0010, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0101,
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
/* 50 */
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
0x0101, 0x0101, 0x0101, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* 60 */
0x0010, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0102,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
/* 70 */
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0102, 0x0102, 0x0102, 0x0010, 0x0010, 0x0010, 0x0010, 0x0020,
/* 80 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
/* 90 */
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
/* a0 */
0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* b0 */
0x0010, 0x0010, 0x0014, 0x0014, 0x0010, 0x0010, 0x0010, 0x0010,
0x0010, 0x0014, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
/* c0 */
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
/* d0 */
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0010,
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0102,
/* e0 */
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
/* f0 */
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0010,
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102
};
/*********************************************************************
* _wcsicmp (NTDLL.@)
*/
@ -308,24 +361,20 @@ ULONG __cdecl NTDLL_wcstoul(LPCWSTR s, LPWSTR *end, INT base)
/*********************************************************************
* iswctype (NTDLL.@)
*/
INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct )
INT __cdecl NTDLL_iswctype( WCHAR wc, unsigned short type )
{
return (get_char_typeW(wc) & 0xfff) & wct;
if (wc >= 256) return 0;
return wctypes[wc] & type;
}
/*********************************************************************
* iswalpha (NTDLL.@)
*
* Checks if a unicode char wc is a letter
*
* RETURNS
* TRUE: The unicode char wc is a letter.
* FALSE: Otherwise
*/
INT __cdecl NTDLL_iswalpha( WCHAR wc )
{
return isalphaW(wc);
if (wc >= 256) return 0;
return wctypes[wc] & (C1_ALPHA | C1_UPPER | C1_LOWER);
}
@ -340,7 +389,8 @@ INT __cdecl NTDLL_iswalpha( WCHAR wc )
*/
INT __cdecl NTDLL_iswdigit( WCHAR wc )
{
return isdigitW(wc);
if (wc >= 256) return 0;
return wctypes[wc] & C1_DIGIT;
}
@ -355,7 +405,8 @@ INT __cdecl NTDLL_iswdigit( WCHAR wc )
*/
INT __cdecl NTDLL_iswlower( WCHAR wc )
{
return islowerW(wc);
if (wc >= 256) return 0;
return wctypes[wc] & C1_LOWER;
}
@ -370,7 +421,8 @@ INT __cdecl NTDLL_iswlower( WCHAR wc )
*/
INT __cdecl NTDLL_iswspace( WCHAR wc )
{
return isspaceW(wc);
if (wc >= 256) return 0;
return wctypes[wc] & C1_SPACE;
}
@ -385,7 +437,8 @@ INT __cdecl NTDLL_iswspace( WCHAR wc )
*/
INT __cdecl NTDLL_iswxdigit( WCHAR wc )
{
return isxdigitW(wc);
if (wc >= 256) return 0;
return wctypes[wc] & C1_XDIGIT;
}
@ -654,9 +707,7 @@ LONG __cdecl _wtol( LPCWSTR str )
ULONG RunningTotal = 0;
BOOL bMinus = FALSE;
while (isspaceW(*str)) {
str++;
} /* while */
while (NTDLL_iswspace(*str)) str++;
if (*str == '+') {
str++;
@ -717,9 +768,7 @@ LONGLONG __cdecl _wtoi64( LPCWSTR str )
ULONGLONG RunningTotal = 0;
BOOL bMinus = FALSE;
while (isspaceW(*str)) {
str++;
} /* while */
while (NTDLL_iswspace(*str)) str++;
if (*str == '+') {
str++;