Added patch to add UTF7 encoding/decoding support.

This commit is contained in:
Sebastian Lackner 2014-10-09 05:47:51 +02:00
parent 5ee11fd2d6
commit 04467e7e68
7 changed files with 1127 additions and 1 deletions

View File

@ -35,10 +35,11 @@ Wine. All those differences are also documented on the
Included bugfixes and improvements
==================================
**Bugfixes and features included in the next upcoming release [3]:**
**Bugfixes and features included in the next upcoming release [4]:**
* Anno 1602 installer depends on Windows 98 behavior of SHFileOperationW
* FEAR 1 installer expects basic_string_wchar_dtor to return NULL ([Wine Bug #37358](http://bugs.winehq.org/show_bug.cgi?id=37358))
* Support for UTF7 encoding/decoding ([Wine Bug #27388](http://bugs.winehq.org/show_bug.cgi?id=27388))
* Wine ignores IDF_CHECKFIRST flag in SetupPromptForDisk ([Wine Bug #20465](http://bugs.winehq.org/show_bug.cgi?id=20465))

2
debian/changelog vendored
View File

@ -2,6 +2,8 @@ wine-compholio (1.7.29) UNRELEASED; urgency=low
* Updated DOS Attributes patch to better detect XATTR functions.
* Added patch to support IDF_CHECKFIRST in SetupPromptForDisk.
* Added patch to fix issues when executing pages with guard page / write watch permissions.
* Added patch to set return value of basic_string_wchar_dtor to return NULL.
* Added patch for UTF7 encoding/decoding support.
* Removed patch to fix issues with drag image in ImageLists (accepted upstream).
* Removed patch to set ldr.EntryPoint for main executable (accepted upstream).
* Removed patch to implement stubs for [Get|Set]SystemFileCacheSize (accepted upstream).

View File

@ -36,6 +36,7 @@ PATCHLIST := \
kernel32-GetSystemTimes.ok \
kernel32-GetVolumePathName.ok \
kernel32-Named_Pipe.ok \
kernel32-UTF7_Support.ok \
libs-Unicode_Collation.ok \
msvcp60-basic_string_wchar_dtor.ok \
ntdll-ATL_Thunk.ok \
@ -482,6 +483,26 @@ kernel32-Named_Pipe.ok:
echo '+ { "kernel32-Named_Pipe", "Dan Kegel", "Fix for ConnectNamedPort return value in overlapped mode." },'; \
) > kernel32-Named_Pipe.ok
# Patchset kernel32-UTF7_Support
# |
# | Included patches:
# | * Support for UTF7 encoding/decoding [by Alex Henrie]
# |
# | This patchset fixes the following Wine bugs:
# | * [#27388] Support for UTF7 encoding/decoding
# |
# | Modified files:
# | * dlls/kernel32/locale.c, dlls/kernel32/tests/codepage.c
# |
.INTERMEDIATE: kernel32-UTF7_Support.ok
kernel32-UTF7_Support.ok:
$(call APPLY_FILE,kernel32-UTF7_Support/0001-kernel32-Support-UTF-7-in-MultiByteToWideChar.patch)
$(call APPLY_FILE,kernel32-UTF7_Support/0002-kernel32-Support-UTF-7-in-WideCharToMultiByte.patch)
$(call APPLY_FILE,kernel32-UTF7_Support/0003-kernel32-tests-Add-tests-for-UTF-7-conversion.patch)
@( \
echo '+ { "kernel32-UTF7_Support", "Alex Henrie", "Support for UTF7 encoding/decoding" },'; \
) > kernel32-UTF7_Support.ok
# Patchset libs-Unicode_Collation
# |
# | Included patches:

View File

@ -0,0 +1,198 @@
From 87874c02de939388405ebfcb752918c1a764a516 Mon Sep 17 00:00:00 2001
From: Alex Henrie <alexhenrie24@gmail.com>
Date: Wed, 8 Oct 2014 21:16:37 -0600
Subject: kernel32: Support UTF-7 in MultiByteToWideChar.
---
dlls/kernel32/locale.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 157 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 730574b..a5d4403 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -1954,6 +1954,160 @@ BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum, DWORD fla
/***********************************************************************
+ * write_to_w_string
+ *
+ * Helper for utf7_mbstowcs
+ *
+ * RETURNS
+ * TRUE on success, FALSE on error
+ */
+static inline BOOL write_to_w_string(WCHAR *dst, int dstlen, int *index, WCHAR character)
+{
+ if (dst)
+ {
+ if (*index >= dstlen)
+ return FALSE;
+
+ dst[*index] = character;
+ }
+
+ (*index)++;
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * utf7_mbstowcs
+ *
+ * UTF-7 to UTF-16 string conversion, helper for MultiByteToWideChar
+ *
+ * RETURNS
+ * On success, the number of characters written
+ * On dst buffer overflow, -1
+ */
+static int utf7_mbstowcs(const char *src, int srclen, WCHAR *dst, int dstlen)
+{
+ static const WCHAR base64_decoding_table[] = {
+ /* \0 */ -1, /* \x01 */ -1, /* \x02 */ -1, /* \x03 */ -1,
+ /* \x04 */ -1, /* \x05 */ -1, /* \x06 */ -1, /* \a */ -1,
+ /* \b */ -1, /* \t */ -1, /* \n */ -1, /* \v */ -1,
+ /* \f */ -1, /* \r */ -1, /* \x0E */ -1, /* \x0F */ -1,
+ /* \x10 */ -1, /* \x11 */ -1, /* \x12 */ -1, /* \x13 */ -1,
+ /* \x14 */ -1, /* \x15 */ -1, /* \x16 */ -1, /* \x17 */ -1,
+ /* \x18 */ -1, /* \x19 */ -1, /* \x1A */ -1, /* \e */ -1,
+ /* \x1C */ -1, /* \x1D */ -1, /* \x1E */ -1, /* \x1F */ -1,
+ /* */ -1, /* ! */ -1, /* " */ -1, /* # */ -1,
+ /* $ */ -1, /* % */ -1, /* & */ -1, /* ' */ -1,
+ /* ( */ -1, /* ) */ -1, /* * */ -1, /* + */ 62,
+ /* , */ -1, /* - */ -1, /* . */ -1, /* / */ 63,
+ /* 0 */ 52, /* 1 */ 53, /* 2 */ 54, /* 3 */ 55,
+ /* 4 */ 56, /* 5 */ 57, /* 6 */ 58, /* 7 */ 59,
+ /* 8 */ 60, /* 9 */ 61, /* : */ -1, /* ; */ -1,
+ /* < */ -1, /* = */ -1, /* > */ -1, /* ? */ -1,
+ /* @ */ -1, /* A */ 0, /* B */ 1, /* C */ 2,
+ /* D */ 3, /* E */ 4, /* F */ 5, /* G */ 6,
+ /* H */ 7, /* I */ 8, /* J */ 9, /* K */ 10,
+ /* L */ 11, /* M */ 12, /* N */ 13, /* O */ 14,
+ /* P */ 15, /* Q */ 16, /* R */ 17, /* S */ 18,
+ /* T */ 19, /* U */ 20, /* V */ 21, /* W */ 22,
+ /* X */ 23, /* Y */ 24, /* Z */ 25, /* [ */ -1,
+ /* \ */ -1, /* ] */ -1, /* ^ */ -1, /* _ */ -1,
+ /* ` */ -1, /* a */ 26, /* b */ 27, /* c */ 28,
+ /* d */ 29, /* e */ 30, /* f */ 31, /* g */ 32,
+ /* h */ 33, /* i */ 34, /* j */ 35, /* k */ 36,
+ /* l */ 37, /* m */ 38, /* n */ 39, /* o */ 40,
+ /* p */ 41, /* q */ 42, /* r */ 43, /* s */ 44,
+ /* t */ 45, /* u */ 46, /* v */ 47, /* w */ 48,
+ /* x */ 49, /* y */ 50, /* z */ 51, /* { */ -1,
+ /* | */ -1, /* } */ -1, /* ~ */ -1, /* \x7F */ -1
+ };
+
+ const char *source_end = src + srclen;
+ int dest_index = 0;
+
+ DWORD byte_pair = 0;
+ short offset = 0;
+
+ /* MultiByteToWideChar guarantees that srclen > 0 */
+ assert(srclen > 0);
+
+ if (!dstlen)
+ dst = NULL;
+
+ do
+ {
+ if (*src == '+')
+ {
+ src++; /* skip the + sign */
+
+ if (*src == '-')
+ {
+ /* just a plus sign escaped as +- */
+ if (!write_to_w_string(dst, dstlen, &dest_index, '+'))
+ return -1;
+ src++;
+ continue;
+ }
+
+ do
+ {
+ WCHAR sextet = *src;
+ if (sextet == '-')
+ {
+ /* skip over the dash and end base64 decoding */
+ /* the current, unfinished byte pair is discarded */
+ src++;
+ offset = 0;
+ break;
+ }
+ else if (sextet <= 127)
+ {
+ sextet = base64_decoding_table[sextet];
+ if (sextet == (WCHAR)-1)
+ {
+ /* -1 means that the next character of src is not part of a base64 sequence */
+ /* in other words, all sextets in this base64 sequence have been processed */
+ /* the current, unfinished byte pair is discarded */
+ offset = 0;
+ break;
+ }
+ }
+ else
+ {
+ /* the next character of src is > 127 and therefore not part of a base64 sequence */
+ /* the current, unfinished byte pair is NOT discarded in this case */
+ /* this is probably a bug in Windows */
+ break;
+ }
+
+ byte_pair = (byte_pair << 6) | sextet;
+ offset += 6;
+
+ if (offset >= 16)
+ {
+ /* this byte pair is done */
+ if (!write_to_w_string(dst, dstlen, &dest_index, (byte_pair >> (offset - 16)) & 0xFFFF ))
+ return -1;
+ offset -= 16;
+ }
+
+ /* this sextet is done */
+ src++;
+ } while (src < source_end);
+ }
+ else
+ {
+ /* we have to convert to unsigned char in case *src > 127 */
+ if (!write_to_w_string(dst, dstlen, &dest_index, (unsigned char)*src))
+ return -1;
+ src++;
+ }
+ } while (src < source_end);
+
+ return dest_index;
+}
+
+/***********************************************************************
* MultiByteToWideChar (KERNEL32.@)
*
* Convert a multibyte character string into a Unicode string.
@@ -1963,7 +2117,7 @@ BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum, DWORD fla
* flags [I] Character mapping flags
* src [I] Source string buffer
* srclen [I] Length of src (in bytes), or -1 if src is NUL terminated
- * dst [O] Destination buffer
+ * dst [O] Destination buffer, or NULL to compute the required length
* dstlen [I] Length of dst (in WCHARs), or 0 to compute the required length
*
* RETURNS
@@ -2006,9 +2160,8 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
- FIXME("UTF-7 not supported\n");
- SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
- return 0;
+ ret = utf7_mbstowcs( src, srclen, dst, dstlen );
+ break;
case CP_UNIXCP:
if (unix_cptable)
{
--
2.1.2

View File

@ -0,0 +1,183 @@
From eb7a37bf7d71cfa8696185047483fbe02d01a5d1 Mon Sep 17 00:00:00 2001
From: Alex Henrie <alexhenrie24@gmail.com>
Date: Wed, 8 Oct 2014 21:18:22 -0600
Subject: kernel32: Support UTF-7 in WideCharToMultiByte.
---
dlls/kernel32/locale.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 142 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index a5d4403..fc0a7ad 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -2201,6 +2201,145 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
/***********************************************************************
+ * can_directly_encode
+ *
+ * Helper for utf7_wcstombs
+ */
+static inline BOOL utf7_can_directly_encode(WCHAR codepoint)
+{
+ static const BOOL directly_encodable_table[] = {
+ /* \0 */ TRUE, /* \x01 */ FALSE, /* \x02 */ FALSE, /* \x03 */ FALSE,
+ /* \x04 */ FALSE, /* \x05 */ FALSE, /* \x06 */ FALSE, /* \a */ FALSE,
+ /* \b */ FALSE, /* \t */ TRUE, /* \n */ TRUE, /* \v */ FALSE,
+ /* \f */ FALSE, /* \r */ TRUE, /* \x0E */ FALSE, /* \x0F */ FALSE,
+ /* \x10 */ FALSE, /* \x11 */ FALSE, /* \x12 */ FALSE, /* \x13 */ FALSE,
+ /* \x14 */ FALSE, /* \x15 */ FALSE, /* \x16 */ FALSE, /* \x17 */ FALSE,
+ /* \x18 */ FALSE, /* \x19 */ FALSE, /* \x1A */ FALSE, /* \e */ FALSE,
+ /* \x1C */ FALSE, /* \x1D */ FALSE, /* \x1E */ FALSE, /* \x1F */ FALSE,
+ /* */ TRUE, /* ! */ FALSE, /* " */ FALSE, /* # */ FALSE,
+ /* $ */ FALSE, /* % */ FALSE, /* & */ FALSE, /* ' */ TRUE,
+ /* ( */ TRUE, /* ) */ TRUE, /* * */ FALSE, /* + */ TRUE,
+ /* , */ TRUE, /* - */ TRUE, /* . */ TRUE, /* / */ TRUE,
+ /* 0 */ TRUE, /* 1 */ TRUE, /* 2 */ TRUE, /* 3 */ TRUE,
+ /* 4 */ TRUE, /* 5 */ TRUE, /* 6 */ TRUE, /* 7 */ TRUE,
+ /* 8 */ TRUE, /* 9 */ TRUE, /* : */ TRUE, /* ; */ FALSE,
+ /* < */ FALSE, /* = */ FALSE, /* > */ FALSE, /* ? */ TRUE,
+ /* @ */ FALSE, /* A */ TRUE, /* B */ TRUE, /* C */ TRUE,
+ /* D */ TRUE, /* E */ TRUE, /* F */ TRUE, /* G */ TRUE,
+ /* H */ TRUE, /* I */ TRUE, /* J */ TRUE, /* K */ TRUE,
+ /* L */ TRUE, /* M */ TRUE, /* N */ TRUE, /* O */ TRUE,
+ /* P */ TRUE, /* Q */ TRUE, /* R */ TRUE, /* S */ TRUE,
+ /* T */ TRUE, /* U */ TRUE, /* V */ TRUE, /* W */ TRUE,
+ /* X */ TRUE, /* Y */ TRUE, /* Z */ TRUE, /* [ */ FALSE,
+ /* \ */ FALSE, /* ] */ FALSE, /* ^ */ FALSE, /* _ */ FALSE,
+ /* ` */ FALSE, /* a */ TRUE, /* b */ TRUE, /* c */ TRUE,
+ /* d */ TRUE, /* e */ TRUE, /* f */ TRUE, /* g */ TRUE,
+ /* h */ TRUE, /* i */ TRUE, /* j */ TRUE, /* k */ TRUE,
+ /* l */ TRUE, /* m */ TRUE, /* n */ TRUE, /* o */ TRUE,
+ /* p */ TRUE, /* q */ TRUE, /* r */ TRUE, /* s */ TRUE,
+ /* t */ TRUE, /* u */ TRUE, /* v */ TRUE, /* w */ TRUE,
+ /* x */ TRUE, /* y */ TRUE, /* z */ TRUE
+ };
+
+ return codepoint <= 'z' ? directly_encodable_table[codepoint] : FALSE;
+}
+
+/***********************************************************************
+ * write_to_c_string
+ *
+ * Helper for utf7_wcstombs
+ *
+ * RETURNS
+ * TRUE on success, FALSE on error
+ */
+static inline BOOL write_to_c_string(char *dst, int dstlen, int *index, char character)
+{
+ if (dst)
+ {
+ if (*index >= dstlen)
+ return FALSE;
+
+ dst[*index] = character;
+ }
+
+ (*index)++;
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * utf7_wcstombs
+ *
+ * UTF-16 to UTF-7 string conversion, helper for WideCharToMultiByte
+ *
+ * RETURNS
+ * On success, the number of characters written
+ * On dst buffer overflow, -1
+ */
+static int utf7_wcstombs(const WCHAR *src, int srclen, char *dst, int dstlen)
+{
+ static const char base64_encoding_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ const WCHAR *source_end = src + srclen;
+ int dest_index = 0;
+
+ if (!dstlen)
+ dst = NULL;
+
+ while (src < source_end)
+ {
+ if (*src == '+')
+ {
+ if (!write_to_c_string(dst, dstlen, &dest_index, '+'))
+ return -1;
+ if (!write_to_c_string(dst, dstlen, &dest_index, '-'))
+ return -1;
+ src++;
+ }
+ else if (utf7_can_directly_encode(*src))
+ {
+ if (!write_to_c_string(dst, dstlen, &dest_index, *src))
+ return -1;
+ src++;
+ }
+ else
+ {
+ unsigned int offset = 0;
+ DWORD byte_pair = 0;
+
+ if (!write_to_c_string(dst, dstlen, &dest_index, '+'))
+ return -1;
+
+ while (src < source_end && !utf7_can_directly_encode(*src))
+ {
+ byte_pair = (byte_pair << 16) | *src;
+ offset += 16;
+ while (offset >= 6)
+ {
+ if (!write_to_c_string(dst, dstlen, &dest_index, base64_encoding_table[(byte_pair >> (offset - 6)) & 0x3F]))
+ return -1;
+ offset -= 6;
+ }
+ src++;
+ }
+
+ if (offset)
+ {
+ byte_pair <<= (6 - offset);
+ if (!write_to_c_string(dst, dstlen, &dest_index, base64_encoding_table[byte_pair & 0x3F]))
+ return -1;
+ }
+
+ /* Windows always explicitly terminates the base64 sequence even though RFC 2152 (page 3, rule 2) does not require this */
+ if (!write_to_c_string(dst, dstlen, &dest_index, '-'))
+ return -1;
+ }
+ }
+
+ return dest_index;
+}
+
+/***********************************************************************
* WideCharToMultiByte (KERNEL32.@)
*
* Convert a Unicode character string into a multibyte string.
@@ -2210,7 +2349,7 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
* flags [I] Mapping Flags (MB_ constants from "winnls.h").
* src [I] Source string buffer
* srclen [I] Length of src (in WCHARs), or -1 if src is NUL terminated
- * dst [O] Destination buffer
+ * dst [O] Destination buffer, or NULL to compute the required length
* dstlen [I] Length of dst (in bytes), or 0 to compute the required length
* defchar [I] Default character to use for conversion if no exact
* conversion can be made
@@ -2267,9 +2406,8 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
- FIXME("UTF-7 not supported\n");
- SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
- return 0;
+ ret = utf7_wcstombs( src, srclen, dst, dstlen );
+ break;
case CP_UNIXCP:
if (unix_cptable)
{
--
2.1.2

View File

@ -0,0 +1,4 @@
Author: Alex Henrie
Subject: Support for UTF7 encoding/decoding
Revision: 1
Fixes: [27388] Support for UTF7 encoding/decoding