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 (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) static void InitFunctionPtrs(void)
{ {
hntdll = LoadLibraryA("ntdll.dll"); hntdll = LoadLibraryA("ntdll.dll");
@ -116,6 +123,12 @@ static void InitFunctionPtrs(void)
X(toupper); X(toupper);
X(_strnicmp); X(_strnicmp);
X(sscanf); X(sscanf);
X(iswctype);
X(iswalpha);
X(iswdigit);
X(iswlower);
X(iswspace);
X(iswxdigit);
#undef X #undef X
} }
@ -957,7 +970,11 @@ static void test_wtol(void)
"(test %d): call failed: _wtol(\"%s\") has result %d, expected: %d\n", "(test %d): call failed: _wtol(\"%s\") has result %d, expected: %d\n",
test_num, str2long[test_num].str, result, str2long[test_num].value); test_num, str2long[test_num].str, result, str2long[test_num].value);
pRtlFreeUnicodeString(&uni); 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)); wine_dbgstr_longlong(str2longlong[test_num].value));
pRtlFreeUnicodeString(&uni); 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) static void test_wcschr(void)
@ -1569,6 +1590,74 @@ static void test_sscanf(void)
ok(d == 0.0, "d = %lf\n", f); 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) START_TEST(string)
{ {
InitFunctionPtrs(); InitFunctionPtrs();
@ -1595,4 +1684,5 @@ START_TEST(string)
test__strnicmp(); test__strnicmp();
test_wcsicmp(); test_wcsicmp();
test_sscanf(); test_sscanf();
test_wctype();
} }

View File

@ -33,6 +33,59 @@
#include "winternl.h" #include "winternl.h"
#include "wine/unicode.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.@) * _wcsicmp (NTDLL.@)
*/ */
@ -308,24 +361,20 @@ ULONG __cdecl NTDLL_wcstoul(LPCWSTR s, LPWSTR *end, INT base)
/********************************************************************* /*********************************************************************
* iswctype (NTDLL.@) * 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.@) * 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 ) 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 ) 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 ) 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 ) 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 ) 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; ULONG RunningTotal = 0;
BOOL bMinus = FALSE; BOOL bMinus = FALSE;
while (isspaceW(*str)) { while (NTDLL_iswspace(*str)) str++;
str++;
} /* while */
if (*str == '+') { if (*str == '+') {
str++; str++;
@ -717,9 +768,7 @@ LONGLONG __cdecl _wtoi64( LPCWSTR str )
ULONGLONG RunningTotal = 0; ULONGLONG RunningTotal = 0;
BOOL bMinus = FALSE; BOOL bMinus = FALSE;
while (isspaceW(*str)) { while (NTDLL_iswspace(*str)) str++;
str++;
} /* while */
if (*str == '+') { if (*str == '+') {
str++; str++;