Alexandre Julliard : kernelbase: Use RtlNormalizeString() directly in FoldStringW().
Alexandre Julliard
julliard at winehq.org
Mon Feb 3 15:06:05 CST 2020
Module: wine
Branch: master
Commit: f0a82c3a2aa324d410d0d706aad80da430a0cb21
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f0a82c3a2aa324d410d0d706aad80da430a0cb21
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 3 16:31:08 2020 +0100
kernelbase: Use RtlNormalizeString() directly in FoldStringW().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernelbase/locale.c | 163 +++++++++++++++++++++++++++++------------------
1 file changed, 102 insertions(+), 61 deletions(-)
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 9953bf7e1a..c697da16eb 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -836,9 +836,10 @@ static const WCHAR *get_ligature( WCHAR wc )
}
-static int expand_ligatures( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
+static NTSTATUS expand_ligatures( const WCHAR *src, int srclen, WCHAR *dst, int *dstlen )
{
int i, len, pos = 0;
+ NTSTATUS ret = STATUS_SUCCESS;
const WCHAR *expand;
for (i = 0; i < srclen; i++)
@@ -850,30 +851,93 @@ static int expand_ligatures( const WCHAR *src, int srclen, WCHAR *dst, int dstle
}
else len = lstrlenW( expand );
- if (dstlen)
+ if (*dstlen && ret == STATUS_SUCCESS)
{
- if (pos + len > dstlen) break;
- memcpy( dst + pos, expand, len * sizeof(WCHAR) );
+ if (pos + len <= *dstlen) memcpy( dst + pos, expand, len * sizeof(WCHAR) );
+ else ret = STATUS_BUFFER_TOO_SMALL;
}
pos += len;
}
- return pos;
+ *dstlen = pos;
+ return ret;
}
-static int fold_digits( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
+static NTSTATUS fold_digits( const WCHAR *src, int srclen, WCHAR *dst, int *dstlen )
{
extern const WCHAR wine_digitmap[] DECLSPEC_HIDDEN;
- int i;
+ int i, len = *dstlen;
- if (!dstlen) return srclen;
- if (srclen > dstlen) return 0;
+ *dstlen = srclen;
+ if (!len) return STATUS_SUCCESS;
+ if (srclen > len) return STATUS_BUFFER_TOO_SMALL;
for (i = 0; i < srclen; i++)
{
WCHAR digit = get_table_entry( wine_digitmap, src[i] );
dst[i] = digit ? digit : src[i];
}
- return srclen;
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS fold_string( DWORD flags, const WCHAR *src, int srclen, WCHAR *dst, int *dstlen )
+{
+ NTSTATUS ret;
+ WCHAR *tmp;
+
+ switch (flags)
+ {
+ case MAP_PRECOMPOSED:
+ return RtlNormalizeString( NormalizationC, src, srclen, dst, dstlen );
+ case MAP_FOLDCZONE:
+ case MAP_PRECOMPOSED | MAP_FOLDCZONE:
+ return RtlNormalizeString( NormalizationKC, src, srclen, dst, dstlen );
+ case MAP_COMPOSITE:
+ return RtlNormalizeString( NormalizationD, src, srclen, dst, dstlen );
+ case MAP_COMPOSITE | MAP_FOLDCZONE:
+ return RtlNormalizeString( NormalizationKD, src, srclen, dst, dstlen );
+ case MAP_FOLDDIGITS:
+ return fold_digits( src, srclen, dst, dstlen );
+ case MAP_EXPAND_LIGATURES:
+ case MAP_EXPAND_LIGATURES | MAP_FOLDCZONE:
+ return expand_ligatures( src, srclen, dst, dstlen );
+ case MAP_FOLDDIGITS | MAP_PRECOMPOSED:
+ if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) )))
+ return STATUS_NO_MEMORY;
+ fold_digits( src, srclen, tmp, &srclen );
+ ret = RtlNormalizeString( NormalizationC, tmp, srclen, dst, dstlen );
+ break;
+ case MAP_FOLDDIGITS | MAP_FOLDCZONE:
+ case MAP_FOLDDIGITS | MAP_PRECOMPOSED | MAP_FOLDCZONE:
+ if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) )))
+ return STATUS_NO_MEMORY;
+ fold_digits( src, srclen, tmp, &srclen );
+ ret = RtlNormalizeString( NormalizationKC, tmp, srclen, dst, dstlen );
+ break;
+ case MAP_FOLDDIGITS | MAP_COMPOSITE:
+ if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) )))
+ return STATUS_NO_MEMORY;
+ fold_digits( src, srclen, tmp, &srclen );
+ ret = RtlNormalizeString( NormalizationD, tmp, srclen, dst, dstlen );
+ break;
+ case MAP_FOLDDIGITS | MAP_COMPOSITE | MAP_FOLDCZONE:
+ if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) )))
+ return STATUS_NO_MEMORY;
+ fold_digits( src, srclen, tmp, &srclen );
+ ret = RtlNormalizeString( NormalizationKD, tmp, srclen, dst, dstlen );
+ break;
+ case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS:
+ case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS | MAP_FOLDCZONE:
+ if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) )))
+ return STATUS_NO_MEMORY;
+ fold_digits( src, srclen, tmp, &srclen );
+ ret = expand_ligatures( tmp, srclen, dst, dstlen );
+ break;
+ default:
+ return STATUS_INVALID_PARAMETER_1;
+ }
+ RtlFreeHeap( GetProcessHeap(), 0, tmp );
+ return ret;
}
@@ -3280,8 +3344,9 @@ INT WINAPI DECLSPEC_HOTPATCH FindStringOrdinal( DWORD flag, const WCHAR *src, IN
*/
INT WINAPI DECLSPEC_HOTPATCH FoldStringW( DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen )
{
- WCHAR *tmp;
- int ret;
+ NTSTATUS status;
+ WCHAR *buf = dst;
+ int len = dstlen;
if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
{
@@ -3290,60 +3355,36 @@ INT WINAPI DECLSPEC_HOTPATCH FoldStringW( DWORD flags, LPCWSTR src, INT srclen,
}
if (srclen == -1) srclen = lstrlenW(src) + 1;
- switch (flags)
+ if (!dstlen && (flags & (MAP_PRECOMPOSED | MAP_FOLDCZONE | MAP_COMPOSITE)))
{
- case MAP_PRECOMPOSED:
- return NormalizeString( NormalizationC, src, srclen, dst, dstlen );
- case MAP_FOLDCZONE:
- case MAP_PRECOMPOSED | MAP_FOLDCZONE:
- return NormalizeString( NormalizationKC, src, srclen, dst, dstlen );
- case MAP_COMPOSITE:
- return NormalizeString( NormalizationD, src, srclen, dst, dstlen );
- case MAP_COMPOSITE | MAP_FOLDCZONE:
- return NormalizeString( NormalizationKD, src, srclen, dst, dstlen );
- case MAP_FOLDDIGITS:
- return fold_digits( src, srclen, dst, dstlen );
- case MAP_EXPAND_LIGATURES:
- case MAP_EXPAND_LIGATURES | MAP_FOLDCZONE:
- return expand_ligatures( src, srclen, dst, dstlen );
- case MAP_FOLDDIGITS | MAP_PRECOMPOSED:
- if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
- if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
- ret = NormalizeString( NormalizationC, tmp, srclen, dst, dstlen );
- break;
- case MAP_FOLDDIGITS | MAP_FOLDCZONE:
- case MAP_FOLDDIGITS | MAP_PRECOMPOSED | MAP_FOLDCZONE:
- if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
- if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
- ret = NormalizeString( NormalizationKC, tmp, srclen, dst, dstlen );
- break;
- case MAP_FOLDDIGITS | MAP_COMPOSITE:
- if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
- if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
- ret = NormalizeString( NormalizationD, tmp, srclen, dst, dstlen );
- break;
- case MAP_FOLDDIGITS | MAP_COMPOSITE | MAP_FOLDCZONE:
- if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
- if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
- ret = NormalizeString( NormalizationKD, tmp, srclen, dst, dstlen );
- break;
- case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS:
- case MAP_EXPAND_LIGATURES | MAP_FOLDDIGITS | MAP_FOLDCZONE:
- if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0, srclen * sizeof(WCHAR) ))) break;
- if (!(ret = fold_digits( src, srclen, tmp, srclen ))) break;
- ret = expand_ligatures( tmp, srclen, dst, dstlen );
- break;
- default:
- SetLastError( ERROR_INVALID_FLAGS );
- return 0;
+ len = srclen * 4;
+ if (!(buf = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return 0;
+ }
}
- if (!tmp)
+
+ for (;;)
{
- SetLastError( ERROR_OUTOFMEMORY );
+ status = fold_string( flags, src, srclen, buf, &len );
+ if (buf != dst) RtlFreeHeap( GetProcessHeap(), 0, buf );
+ if (status != STATUS_BUFFER_TOO_SMALL) break;
+ if (!(buf = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return 0;
+ }
+ }
+ if (status == STATUS_INVALID_PARAMETER_1)
+ {
+ SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
- RtlFreeHeap( GetProcessHeap(), 0, tmp );
- return ret;
+ if (!set_ntstatus( status )) return 0;
+
+ if (dstlen && dstlen < len) SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return len;
}
More information about the wine-cvs
mailing list