From 16885f09a5383ad56b730c4495da18bb2863cbba Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 31 May 2005 13:24:44 +0000 Subject: [PATCH] Fixed RtlIsTextUnicode prototype, and made it properly take into account the results of the tests to determine the return value. --- dlls/advapi32/advapi.c | 18 +++++++++ dlls/advapi32/advapi32.spec | 2 +- dlls/kernel/profile.c | 8 ++-- dlls/ntdll/rtlstr.c | 99 ++++++++++++++++++++++----------------------- include/winbase.h | 2 +- include/winternl.h | 2 +- 6 files changed, 73 insertions(+), 58 deletions(-) diff --git a/dlls/advapi32/advapi.c b/dlls/advapi32/advapi.c index 04c88272e0f..f6d10ce9c08 100644 --- a/dlls/advapi32/advapi.c +++ b/dlls/advapi32/advapi.c @@ -30,6 +30,7 @@ #include "winbase.h" #include "winnls.h" #include "winreg.h" +#include "winternl.h" #include "winerror.h" #include "wine/library.h" @@ -132,6 +133,23 @@ BOOL WINAPI GetCurrentHwProfileW(LPHW_PROFILE_INFOW pInfo) return FALSE; } + +/************************************************************************** + * IsTextUnicode (ADVAPI32.@) + * + * Attempt to guess whether a text buffer is Unicode. + * + * PARAMS + * buf [I] Text buffer to test + * len [I] Length of buf + * flags [O] Destination for test results + */ +BOOL WINAPI IsTextUnicode( LPCVOID buf, INT len, LPINT flags ) +{ + return RtlIsTextUnicode( buf, len, flags ); +} + + /****************************************************************************** * AbortSystemShutdownA [ADVAPI32.@] * diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index 821f6dd4415..c87979e3a31 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -160,7 +160,7 @@ @ stdcall InitiateSystemShutdownExW(wstr wstr long long long long) @ stub InstallApplication @ stub IsProcessRestricted -@ stdcall IsTextUnicode(ptr long ptr) ntdll.RtlIsTextUnicode +@ stdcall IsTextUnicode(ptr long ptr) @ stdcall IsTokenRestricted(long) @ stdcall IsValidAcl(ptr) @ stdcall IsValidSecurityDescriptor(ptr) diff --git a/dlls/kernel/profile.c b/dlls/kernel/profile.c index a17e1bcf32b..b4936d56f06 100644 --- a/dlls/kernel/profile.c +++ b/dlls/kernel/profile.c @@ -282,15 +282,15 @@ static inline int PROFILE_isspaceW(WCHAR c) static inline ENCODING PROFILE_DetectTextEncoding(const void * buffer, int * len) { - DWORD flags = IS_TEXT_UNICODE_SIGNATURE | - IS_TEXT_UNICODE_REVERSE_SIGNATURE | - IS_TEXT_UNICODE_ODD_LENGTH; + int flags = IS_TEXT_UNICODE_SIGNATURE | + IS_TEXT_UNICODE_REVERSE_SIGNATURE | + IS_TEXT_UNICODE_ODD_LENGTH; if (*len >= sizeof(bom_utf8) && !memcmp(buffer, bom_utf8, sizeof(bom_utf8))) { *len = sizeof(bom_utf8); return ENCODING_UTF8; } - RtlIsTextUnicode((void *)buffer, *len, &flags); + RtlIsTextUnicode(buffer, *len, &flags); if (flags & IS_TEXT_UNICODE_SIGNATURE) { *len = sizeof(WCHAR); diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index 7447ea1e33e..cbe0e3c551c 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -1495,13 +1495,6 @@ NTSTATUS WINAPI RtlFindCharInUnicodeString( /* MISC */ -/* Tests that we currently implement */ -#define ITU_IMPLEMENTED_TESTS \ - (IS_TEXT_UNICODE_SIGNATURE | \ - IS_TEXT_UNICODE_REVERSE_SIGNATURE | \ - IS_TEXT_UNICODE_ODD_LENGTH | \ - IS_TEXT_UNICODE_STATISTICS | \ - IS_TEXT_UNICODE_NULL_BYTES) /************************************************************************** * RtlIsTextUnicode (NTDLL.@) @@ -1514,59 +1507,60 @@ NTSTATUS WINAPI RtlFindCharInUnicodeString( * pf [O] Destination for test results * * RETURNS - * The length of the string if all tests were passed, 0 otherwise. + * TRUE if the buffer is likely Unicode, FALSE otherwise. * * FIXME * Should implement more tests. */ -DWORD WINAPI RtlIsTextUnicode( - LPVOID buf, - DWORD len, - DWORD *pf) +BOOLEAN WINAPI RtlIsTextUnicode( LPCVOID buf, INT len, INT *pf ) { - LPWSTR s = buf; - DWORD flags = -1, out_flags = 0; - - if (!len) - goto out; - if (pf) - flags = *pf; - /* - * Apply various tests to the text string. According to the - * docs, each test "passed" sets the corresponding flag in - * the output flags. But some of the tests are mutually - * exclusive, so I don't see how you could pass all tests ... - */ - - /* Check for an odd length ... pass if even. */ - if ((flags & IS_TEXT_UNICODE_ODD_LENGTH) && (len & 1)) - out_flags |= IS_TEXT_UNICODE_ODD_LENGTH; - - /* Check for the special byte order unicode marks. */ - if ((flags & IS_TEXT_UNICODE_SIGNATURE) && *s == 0xFEFF) - out_flags |= IS_TEXT_UNICODE_SIGNATURE; - - if ((flags & IS_TEXT_UNICODE_REVERSE_SIGNATURE) && *s == 0xFFFE) - out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE; + const WCHAR *s = buf; + int i; + unsigned int flags = ~0U, out_flags = 0; + + if (len < sizeof(WCHAR)) + { + /* FIXME: MSDN documents IS_TEXT_UNICODE_BUFFER_TOO_SMALL but there is no such thing... */ + if (pf) *pf = 0; + return FALSE; + } + if (pf) + flags = *pf; + /* + * Apply various tests to the text string. According to the + * docs, each test "passed" sets the corresponding flag in + * the output flags. But some of the tests are mutually + * exclusive, so I don't see how you could pass all tests ... + */ + + /* Check for an odd length ... pass if even. */ + if (len & 1) out_flags |= IS_TEXT_UNICODE_ODD_LENGTH; + + len /= sizeof(WCHAR); + /* Windows only checks the first 256 characters */ + if (len > 256) len = 256; + + /* Check for the special byte order unicode marks. */ + if (*s == 0xFEFF) out_flags |= IS_TEXT_UNICODE_SIGNATURE; + if (*s == 0xFFFE) out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE; /* apply some statistical analysis */ if (flags & IS_TEXT_UNICODE_STATISTICS) { - DWORD i, stats = 0; + int stats = 0; /* FIXME: checks only for ASCII characters in the unicode stream */ - for (i = 0; i < len / sizeof(WCHAR); i++) + for (i = 0; i < len; i++) { if (s[i] <= 255) stats++; } - if (stats > len / sizeof(WCHAR) / 2) + if (stats > len / 2) out_flags |= IS_TEXT_UNICODE_STATISTICS; } /* Check for unicode NULL chars */ if (flags & IS_TEXT_UNICODE_NULL_BYTES) { - DWORD i; - for (i = 0; i < len / sizeof(WCHAR); i++) + for (i = 0; i < len; i++) { if (!s[i]) { @@ -1576,16 +1570,19 @@ DWORD WINAPI RtlIsTextUnicode( } } - /* - * Check whether the string passed all of the tests. - */ - flags &= ITU_IMPLEMENTED_TESTS; - if ((out_flags & flags) != flags) - len = 0; -out: - if (pf) - *pf = out_flags; - return len; + if (pf) + { + out_flags &= *pf; + *pf = out_flags; + } + /* check for flags that indicate it's definitely not valid Unicode */ + if (out_flags & (IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_NOT_UNICODE_MASK)) return FALSE; + /* now check for invalid ASCII, and assume Unicode if so */ + if (out_flags & IS_TEXT_UNICODE_NOT_ASCII_MASK) return TRUE; + /* now check for Unicode flags */ + if (out_flags & IS_TEXT_UNICODE_UNICODE_MASK) return TRUE; + /* no flags set */ + return FALSE; } diff --git a/include/winbase.h b/include/winbase.h index 19c2bcc2c75..67b76d8de73 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1520,7 +1520,7 @@ BOOL WINAPI InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *,DWOR BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD); BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); BOOL WINAPI IsSystemResumeAutomatic(void); -BOOL WINAPI IsTextUnicode(CONST LPVOID lpBuffer, int cb, LPINT lpi); +BOOL WINAPI IsTextUnicode(LPCVOID,INT,LPINT); BOOL WINAPI IsTokenRestricted(HANDLE); BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); BOOL WINAPI IsValidSid(PSID); diff --git a/include/winternl.h b/include/winternl.h index 731589c9a6a..0c420bc1285 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1743,7 +1743,7 @@ NTSTATUS WINAPI RtlIntegerToChar(ULONG,ULONG,ULONG,PCHAR); NTSTATUS WINAPI RtlIntegerToUnicodeString(ULONG,ULONG,UNICODE_STRING *); ULONG WINAPI RtlIsDosDeviceName_U(PCWSTR); BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(const UNICODE_STRING*,POEM_STRING,PBOOLEAN); -DWORD WINAPI RtlIsTextUnicode(LPVOID,DWORD,DWORD *); +BOOLEAN WINAPI RtlIsTextUnicode(LPCVOID,INT,INT *); BOOLEAN WINAPI RtlIsValidHandle(const RTL_HANDLE_TABLE *, const RTL_HANDLE *); BOOLEAN WINAPI RtlIsValidIndexHandle(const RTL_HANDLE_TABLE *, ULONG Index, RTL_HANDLE **); -- 2.11.4.GIT