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,717 @@
From 2197e9d68f4400b5c30fbbe787ac308bc8a94908 Mon Sep 17 00:00:00 2001
From: Alex Henrie <alexhenrie24@gmail.com>
Date: Wed, 8 Oct 2014 19:52:55 -0600
Subject: kernel32/tests: Add tests for UTF-7 conversion.
---
dlls/kernel32/tests/codepage.c | 687 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 687 insertions(+)
diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c
index 8423c75..aeca011 100644
--- a/dlls/kernel32/tests/codepage.c
+++ b/dlls/kernel32/tests/codepage.c
@@ -412,6 +412,691 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
}
+static void test_utf7_string_conversion(void)
+{
+ struct utf16_to_utf7_test
+ {
+ WCHAR utf16[32];
+ int utf16_len;
+ char utf7[32];
+ int utf7_len;
+ };
+
+ struct utf16_to_utf7_test utf16_to_utf7_tests[] = {
+ /* test some valid UTF-16 */
+ {
+ {0x4F60,0x597D,0x5417,0},
+ 4,
+ "+T2BZfVQX-",
+ 11
+ },
+ /* tests some invalid UTF-16 */
+ /* (stray lead surrogate) */
+ {
+ {0xD801,0},
+ 2,
+ "+2AE-",
+ 6
+ },
+ /* tests some more invalid UTF-16 */
+ /* (codepoint does not exist) */
+ {
+ {0xFF00,0},
+ 2,
+ "+/wA-",
+ 6
+ }
+ };
+
+ struct utf7_to_utf16_test
+ {
+ char utf7[32];
+ WCHAR utf16[32];
+ int utf16_len;
+ };
+
+ struct utf7_to_utf16_test utf7_to_utf16_tests[] = {
+ /* tests some invalid UTF-7 */
+ /* (number of bits in base64 sequence is not a multiple of 16 and the last bit is a 1) */
+ /* also tests whether the unfinished byte pair is discarded or not */
+ {
+ "+T2B-+T2B-+T2B-hello",
+ {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0},
+ 9
+ },
+ /* tests some more invalid UTF-7 */
+ /* (number of bits in base64 sequence is a multiple of 8 but not a multiple of 16) */
+ /* also tests whether the unfinished byte pair is discarded or not */
+ {
+ "+T2BZ-+T2BZ-+T2BZ-hello",
+ {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0},
+ 9
+ },
+ /* tests UTF-7 followed by characters that should be encoded but aren't */
+ {
+ "+T2BZ-\x82\xFE",
+ {0x4F60,0x0082,0x00FE,0},
+ 4
+ }
+ };
+
+ struct wcstombs_test
+ {
+ /* inputs */
+ WCHAR src[2048];
+ int srclen;
+ int dstlen;
+ /* expected outputs */
+ char dst[2048];
+ int len;
+ DWORD error;
+ };
+
+ struct wcstombs_test wcstombs_tests[] = {
+ /* tests which one-byte characters are base64-encoded and which are not */
+ {
+ {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
+ 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,
+ 70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,
+ 92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
+ 111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,
+ 145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
+ 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,
+ 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,
+ 196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,
+ 213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
+ 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,
+ 247,248,249,250,251,252,253,254,255,256,0},
+ 257,
+ 2047,
+ "+AAEAAgADAAQABQAGAAcACA-\t\n+AAsADA-\r+AA4ADwAQABEAEgATABQAFQAWABc"
+ "AGAAZABoAGwAcAB0AHgAf- +ACEAIgAjACQAJQAm-'()+ACo-+-,-./0123456789:"
+ "+ADsAPAA9AD4-?+AEA-ABCDEFGHIJKLMNOPQRSTUVWXYZ+AFsAXABdAF4AXwBg-abc"
+ "defghijklmnopqrstuvwxyz+AHsAfAB9AH4AfwCAAIEAggCDAIQAhQCGAIcAiACJAI"
+ "oAiwCMAI0AjgCPAJAAkQCSAJMAlACVAJYAlwCYAJkAmgCbAJwAnQCeAJ8AoAChAKIA"
+ "owCkAKUApgCnAKgAqQCqAKsArACtAK4ArwCwALEAsgCzALQAtQC2ALcAuAC5ALoAuw"
+ "C8AL0AvgC/AMAAwQDCAMMAxADFAMYAxwDIAMkAygDLAMwAzQDOAM8A0ADRANIA0wDU"
+ "ANUA1gDXANgA2QDaANsA3ADdAN4A3wDgAOEA4gDjAOQA5QDmAOcA6ADpAOoA6wDsAO"
+ "0A7gDvAPAA8QDyAPMA9AD1APYA9wD4APkA+gD7APwA/QD+AP8BAA-",
+ 579,
+ 0xdeadbeef
+ },
+ /* same as above but surrounding the chars with a non-encoded char */
+ {
+ {' ',0x01,' ',0x02,' ',0x03,' ',0x04,' ',0x05,' ',0x06,' ',0x07,' ',
+ 0x08,' ',0x09,' ',0x0A,' ',0x0B,' ',0x0C,' ',0x0D,' ',0x0E,' ',0x0F,
+ ' ',0x10,' ',0x11,' ',0x12,' ',0x13,' ',0x14,' ',0x15,' ',0x16,' ',
+ 0x17,' ',0x18,' ',0x19,' ',0x1A,' ',0x1B,' ',0x1C,' ',0x1D,' ',0x1E,
+ ' ',0x1F,' ',0x20,' ',0x21,' ',0x22,' ',0x23,' ',0x24,' ',0x25,' ',
+ 0x26,' ',0x27,' ',0x28,' ',0x29,' ',0x2A,' ',0x2B,' ',0x2C,' ',0x2D,
+ ' ',0x2E,' ',0x2F,' ',0x30,' ',0x31,' ',0x32,' ',0x33,' ',0x34,' ',
+ 0x35,' ',0x36,' ',0x37,' ',0x38,' ',0x39,' ',0x3A,' ',0x3B,' ',0x3C,
+ ' ',0x3D,' ',0x3E,' ',0x3F,' ',0x40,' ',0x41,' ',0x42,' ',0x43,' ',
+ 0x44,' ',0x45,' ',0x46,' ',0x47,' ',0x48,' ',0x49,' ',0x4A,' ',0x4B,
+ ' ',0x4C,' ',0x4D,' ',0x4E,' ',0x4F,' ',0x50,' ',0x51,' ',0x52,' ',
+ 0x53,' ',0x54,' ',0x55,' ',0x56,' ',0x57,' ',0x58,' ',0x59,' ',0x5A,
+ ' ',0x5B,' ',0x5C,' ',0x5D,' ',0x5E,' ',0x5F,' ',0x60,' ',0x61,' ',
+ 0x62,' ',0x63,' ',0x64,' ',0x65,' ',0x66,' ',0x67,' ',0x68,' ',0x69,
+ ' ',0x6A,' ',0x6B,' ',0x6C,' ',0x6D,' ',0x6E,' ',0x6F,' ',0x70,' ',
+ 0x71,' ',0x72,' ',0x73,' ',0x74,' ',0x75,' ',0x76,' ',0x77,' ',0x78,
+ ' ',0x79,' ',0x7A,' ',0x7B,' ',0x7C,' ',0x7D,' ',0x7E,' ',0x7F,' ',
+ 0x80,' ',0x81,' ',0x82,' ',0x83,' ',0x84,' ',0x85,' ',0x86,' ',0x87,
+ ' ',0x88,' ',0x89,' ',0x8A,' ',0x8B,' ',0x8C,' ',0x8D,' ',0x8E,' ',
+ 0x8F,' ',0x90,' ',0x91,' ',0x92,' ',0x93,' ',0x94,' ',0x95,' ',0x96,
+ ' ',0x97,' ',0x98,' ',0x99,' ',0x9A,' ',0x9B,' ',0x9C,' ',0x9D,' ',
+ 0x9E,' ',0x9F,' ',0xA0,' ',0xA1,' ',0xA2,' ',0xA3,' ',0xA4,' ',0xA5,
+ ' ',0xA6,' ',0xA7,' ',0xA8,' ',0xA9,' ',0xAA,' ',0xAB,' ',0xAC,' ',
+ 0xAD,' ',0xAE,' ',0xAF,' ',0xB0,' ',0xB1,' ',0xB2,' ',0xB3,' ',0xB4,
+ ' ',0xB5,' ',0xB6,' ',0xB7,' ',0xB8,' ',0xB9,' ',0xBA,' ',0xBB,' ',
+ 0xBC,' ',0xBD,' ',0xBE,' ',0xBF,' ',0xC0,' ',0xC1,' ',0xC2,' ',0xC3,
+ ' ',0xC4,' ',0xC5,' ',0xC6,' ',0xC7,' ',0xC8,' ',0xC9,' ',0xCA,' ',
+ 0xCB,' ',0xCC,' ',0xCD,' ',0xCE,' ',0xCF,' ',0xD0,' ',0xD1,' ',0xD2,
+ ' ',0xD3,' ',0xD4,' ',0xD5,' ',0xD6,' ',0xD7,' ',0xD8,' ',0xD9,' ',
+ 0xDA,' ',0xDB,' ',0xDC,' ',0xDD,' ',0xDE,' ',0xDF,' ',0xE0,' ',0xE1,
+ ' ',0xE2,' ',0xE3,' ',0xE4,' ',0xE5,' ',0xE6,' ',0xE7,' ',0xE8,' ',
+ 0xE9,' ',0xEA,' ',0xEB,' ',0xEC,' ',0xED,' ',0xEE,' ',0xEF,' ',0xF0,
+ ' ',0xF1,' ',0xF2,' ',0xF3,' ',0xF4,' ',0xF5,' ',0xF6,' ',0xF7,' ',
+ 0xF8,' ',0xF9,' ',0xFA,' ',0xFB,' ',0xFC,' ',0xFD,' ',0xFE,' ',0xFF,
+ ' ',0x00,' '},
+ 513,
+ 2047,
+ " +AAE- +AAI- +AAM- +AAQ- +AAU- +AAY- +AAc- +AAg- \t \n +AAs- +AAw-"
+ " \r +AA4- +AA8- +ABA- +ABE- +ABI- +ABM- +ABQ- +ABU- +ABY- +ABc- +A"
+ "Bg- +ABk- +ABo- +ABs- +ABw- +AB0- +AB4- +AB8- +ACE- +ACI- +ACM- "
+ "+ACQ- +ACU- +ACY- ' ( ) +ACo- +- , - . / 0 1 2 3 4 5 6 7 8 9 : +AD"
+ "s- +ADw- +AD0- +AD4- ? +AEA- A B C D E F G H I J K L M N O P Q R S"
+ " T U V W X Y Z +AFs- +AFw- +AF0- +AF4- +AF8- +AGA- a b c d e f g h"
+ " i j k l m n o p q r s t u v w x y z +AHs- +AHw- +AH0- +AH4- +AH8-"
+ " +AIA- +AIE- +AII- +AIM- +AIQ- +AIU- +AIY- +AIc- +AIg- +AIk- +AIo-"
+ " +AIs- +AIw- +AI0- +AI4- +AI8- +AJA- +AJE- +AJI- +AJM- +AJQ- +AJU-"
+ " +AJY- +AJc- +AJg- +AJk- +AJo- +AJs- +AJw- +AJ0- +AJ4- +AJ8- +AKA-"
+ " +AKE- +AKI- +AKM- +AKQ- +AKU- +AKY- +AKc- +AKg- +AKk- +AKo- +AKs-"
+ " +AKw- +AK0- +AK4- +AK8- +ALA- +ALE- +ALI- +ALM- +ALQ- +ALU- +ALY-"
+ " +ALc- +ALg- +ALk- +ALo- +ALs- +ALw- +AL0- +AL4- +AL8- +AMA- +AME-"
+ " +AMI- +AMM- +AMQ- +AMU- +AMY- +AMc- +AMg- +AMk- +AMo- +AMs- +AMw-"
+ " +AM0- +AM4- +AM8- +ANA- +ANE- +ANI- +ANM- +ANQ- +ANU- +ANY- +ANc-"
+ " +ANg- +ANk- +ANo- +ANs- +ANw- +AN0- +AN4- +AN8- +AOA- +AOE- +AOI-"
+ " +AOM- +AOQ- +AOU- +AOY- +AOc- +AOg- +AOk- +AOo- +AOs- +AOw- +AO0-"
+ " +AO4- +AO8- +APA- +APE- +API- +APM- +APQ- +APU- +APY- +APc- +APg-"
+ " +APk- +APo- +APs- +APw- +AP0- +AP4- +AP8- \0 ",
+ 1230,
+ 0xdeadbeef
+ },
+ /* tests which one-byte characters are absorbed into surrounding base64 blocks */
+ /* (Windows always ends the base64 block when it encounters a directly encodable character) */
+ {
+ {0x2672,0x0001,0x2672,0x0002,0x2672,0x0003,0x2672,0x0004,0x2672,
+ 0x0005,0x2672,0x0006,0x2672,0x0007,0x2672,0x0008,0x2672,0x0009,
+ 0x2672,0x000A,0x2672,0x000B,0x2672,0x000C,0x2672,0x000D,0x2672,
+ 0x000E,0x2672,0x000F,0x2672,0x0010,0x2672,0x0011,0x2672,0x0012,
+ 0x2672,0x0013,0x2672,0x0014,0x2672,0x0015,0x2672,0x0016,0x2672,
+ 0x0017,0x2672,0x0018,0x2672,0x0019,0x2672,0x001A,0x2672,0x001B,
+ 0x2672,0x001C,0x2672,0x001D,0x2672,0x001E,0x2672,0x001F,0x2672,
+ 0x0020,0x2672,0x0021,0x2672,0x0022,0x2672,0x0023,0x2672,0x0024,
+ 0x2672,0x0025,0x2672,0x0026,0x2672,0x0027,0x2672,0x0028,0x2672,
+ 0x0029,0x2672,0x002A,0x2672,0x002B,0x2672,0x002C,0x2672,0x002D,
+ 0x2672,0x002E,0x2672,0x002F,0x2672,0x0030,0x2672,0x0031,0x2672,
+ 0x0032,0x2672,0x0033,0x2672,0x0034,0x2672,0x0035,0x2672,0x0036,
+ 0x2672,0x0037,0x2672,0x0038,0x2672,0x0039,0x2672,0x003A,0x2672,
+ 0x003B,0x2672,0x003C,0x2672,0x003D,0x2672,0x003E,0x2672,0x003F,
+ 0x2672,0x0040,0x2672,0x0041,0x2672,0x0042,0x2672,0x0043,0x2672,
+ 0x0044,0x2672,0x0045,0x2672,0x0046,0x2672,0x0047,0x2672,0x0048,
+ 0x2672,0x0049,0x2672,0x004A,0x2672,0x004B,0x2672,0x004C,0x2672,
+ 0x004D,0x2672,0x004E,0x2672,0x004F,0x2672,0x0050,0x2672,0x0051,
+ 0x2672,0x0052,0x2672,0x0053,0x2672,0x0054,0x2672,0x0055,0x2672,
+ 0x0056,0x2672,0x0057,0x2672,0x0058,0x2672,0x0059,0x2672,0x005A,
+ 0x2672,0x005B,0x2672,0x005C,0x2672,0x005D,0x2672,0x005E,0x2672,
+ 0x005F,0x2672,0x0060,0x2672,0x0061,0x2672,0x0062,0x2672,0x0063,
+ 0x2672,0x0064,0x2672,0x0065,0x2672,0x0066,0x2672,0x0067,0x2672,
+ 0x0068,0x2672,0x0069,0x2672,0x006A,0x2672,0x006B,0x2672,0x006C,
+ 0x2672,0x006D,0x2672,0x006E,0x2672,0x006F,0x2672,0x0070,0x2672,
+ 0x0071,0x2672,0x0072,0x2672,0x0073,0x2672,0x0074,0x2672,0x0075,
+ 0x2672,0x0076,0x2672,0x0077,0x2672,0x0078,0x2672,0x0079,0x2672,
+ 0x007A,0x2672,0x007B,0x2672,0x007C,0x2672,0x007D,0x2672,0x007E,
+ 0x2672,0x007F,0x2672,0x0080,0x2672,0x0081,0x2672,0x0082,0x2672,
+ 0x0083,0x2672,0x0084,0x2672,0x0085,0x2672,0x0086,0x2672,0x0087,
+ 0x2672,0x0088,0x2672,0x0089,0x2672,0x008A,0x2672,0x008B,0x2672,
+ 0x008C,0x2672,0x008D,0x2672,0x008E,0x2672,0x008F,0x2672,0x0090,
+ 0x2672,0x0091,0x2672,0x0092,0x2672,0x0093,0x2672,0x0094,0x2672,
+ 0x0095,0x2672,0x0096,0x2672,0x0097,0x2672,0x0098,0x2672,0x0099,
+ 0x2672,0x009A,0x2672,0x009B,0x2672,0x009C,0x2672,0x009D,0x2672,
+ 0x009E,0x2672,0x009F,0x2672,0x00A0,0x2672,0x00A1,0x2672,0x00A2,
+ 0x2672,0x00A3,0x2672,0x00A4,0x2672,0x00A5,0x2672,0x00A6,0x2672,
+ 0x00A7,0x2672,0x00A8,0x2672,0x00A9,0x2672,0x00AA,0x2672,0x00AB,
+ 0x2672,0x00AC,0x2672,0x00AD,0x2672,0x00AE,0x2672,0x00AF,0x2672,
+ 0x00B0,0x2672,0x00B1,0x2672,0x00B2,0x2672,0x00B3,0x2672,0x00B4,
+ 0x2672,0x00B5,0x2672,0x00B6,0x2672,0x00B7,0x2672,0x00B8,0x2672,
+ 0x00B9,0x2672,0x00BA,0x2672,0x00BB,0x2672,0x00BC,0x2672,0x00BD,
+ 0x2672,0x00BE,0x2672,0x00BF,0x2672,0x00C0,0x2672,0x00C1,0x2672,
+ 0x00C2,0x2672,0x00C3,0x2672,0x00C4,0x2672,0x00C5,0x2672,0x00C6,
+ 0x2672,0x00C7,0x2672,0x00C8,0x2672,0x00C9,0x2672,0x00CA,0x2672,
+ 0x00CB,0x2672,0x00CC,0x2672,0x00CD,0x2672,0x00CE,0x2672,0x00CF,
+ 0x2672,0x00D0,0x2672,0x00D1,0x2672,0x00D2,0x2672,0x00D3,0x2672,
+ 0x00D4,0x2672,0x00D5,0x2672,0x00D6,0x2672,0x00D7,0x2672,0x00D8,
+ 0x2672,0x00D9,0x2672,0x00DA,0x2672,0x00DB,0x2672,0x00DC,0x2672,
+ 0x00DD,0x2672,0x00DE,0x2672,0x00DF,0x2672,0x00E0,0x2672,0x00E1,
+ 0x2672,0x00E2,0x2672,0x00E3,0x2672,0x00E4,0x2672,0x00E5,0x2672,
+ 0x00E6,0x2672,0x00E7,0x2672,0x00E8,0x2672,0x00E9,0x2672,0x00EA,
+ 0x2672,0x00EB,0x2672,0x00EC,0x2672,0x00ED,0x2672,0x00EE,0x2672,
+ 0x00EF,0x2672,0x00F0,0x2672,0x00F1,0x2672,0x00F2,0x2672,0x00F3,
+ 0x2672,0x00F4,0x2672,0x00F5,0x2672,0x00F6,0x2672,0x00F7,0x2672,
+ 0x00F8,0x2672,0x00F9,0x2672,0x00FA,0x2672,0x00FB,0x2672,0x00FC,
+ 0x2672,0x00FD,0x2672,0x00FE,0x2672,0x00FF,0x2672,0x0100,0x2672,
+ 0x0000,0x2672},
+ 515,
+ 2047,
+ "+JnIAASZyAAImcgADJnIABCZyAAUmcgAGJnIAByZyAAgmcg-\t+JnI-\n+JnIACyZy"
+ "AAwmcg-\r+JnIADiZyAA8mcgAQJnIAESZyABImcgATJnIAFCZyABUmcgAWJnIAFyZy"
+ "ABgmcgAZJnIAGiZyABsmcgAcJnIAHSZyAB4mcgAfJnI- +JnIAISZyACImcgAjJnIA"
+ "JCZyACUmcgAmJnI-'+JnI-(+JnI-)+JnIAKiZy-+-+JnI-,+JnI--+JnI-.+JnI-/+"
+ "JnI-0+JnI-1+JnI-2+JnI-3+JnI-4+JnI-5+JnI-6+JnI-7+JnI-8+JnI-9+JnI-:+"
+ "JnIAOyZyADwmcgA9JnIAPiZy-?+JnIAQCZy-A+JnI-B+JnI-C+JnI-D+JnI-E+JnI-"
+ "F+JnI-G+JnI-H+JnI-I+JnI-J+JnI-K+JnI-L+JnI-M+JnI-N+JnI-O+JnI-P+JnI-"
+ "Q+JnI-R+JnI-S+JnI-T+JnI-U+JnI-V+JnI-W+JnI-X+JnI-Y+JnI-Z+JnIAWyZyAF"
+ "wmcgBdJnIAXiZyAF8mcgBgJnI-a+JnI-b+JnI-c+JnI-d+JnI-e+JnI-f+JnI-g+Jn"
+ "I-h+JnI-i+JnI-j+JnI-k+JnI-l+JnI-m+JnI-n+JnI-o+JnI-p+JnI-q+JnI-r+Jn"
+ "I-s+JnI-t+JnI-u+JnI-v+JnI-w+JnI-x+JnI-y+JnI-z+JnIAeyZyAHwmcgB9JnIA"
+ "fiZyAH8mcgCAJnIAgSZyAIImcgCDJnIAhCZyAIUmcgCGJnIAhyZyAIgmcgCJJnIAii"
+ "ZyAIsmcgCMJnIAjSZyAI4mcgCPJnIAkCZyAJEmcgCSJnIAkyZyAJQmcgCVJnIAliZy"
+ "AJcmcgCYJnIAmSZyAJomcgCbJnIAnCZyAJ0mcgCeJnIAnyZyAKAmcgChJnIAoiZyAK"
+ "MmcgCkJnIApSZyAKYmcgCnJnIAqCZyAKkmcgCqJnIAqyZyAKwmcgCtJnIAriZyAK8m"
+ "cgCwJnIAsSZyALImcgCzJnIAtCZyALUmcgC2JnIAtyZyALgmcgC5JnIAuiZyALsmcg"
+ "C8JnIAvSZyAL4mcgC/JnIAwCZyAMEmcgDCJnIAwyZyAMQmcgDFJnIAxiZyAMcmcgDI"
+ "JnIAySZyAMomcgDLJnIAzCZyAM0mcgDOJnIAzyZyANAmcgDRJnIA0iZyANMmcgDUJn"
+ "IA1SZyANYmcgDXJnIA2CZyANkmcgDaJnIA2yZyANwmcgDdJnIA3iZyAN8mcgDgJnIA"
+ "4SZyAOImcgDjJnIA5CZyAOUmcgDmJnIA5yZyAOgmcgDpJnIA6iZyAOsmcgDsJnIA7S"
+ "ZyAO4mcgDvJnIA8CZyAPEmcgDyJnIA8yZyAPQmcgD1JnIA9iZyAPcmcgD4JnIA+SZy"
+ "APomcgD7JnIA/CZyAP0mcgD+JnIA/yZyAQAmcg-\0+JnI-",
+ 1428,
+ 0xdeadbeef
+ },
+ /* tests srclen > strlenW(src) */
+ {
+ {'a',0,'b',0},
+ 4,
+ 2047,
+ "a\0b",
+ 4,
+ 0xdeadbeef
+ },
+ /* tests srclen < strlenW(src) with directly encodable chars */
+ {
+ {'h','e','l','l','o',0},
+ 2,
+ 2047,
+ "he",
+ 2,
+ 0xdeadbeef
+ },
+ /* tests srclen < strlenW(src) with non-directly encodable chars*/
+ {
+ {0x4F60,0x597D,0x5417,0},
+ 2,
+ 2047,
+ "+T2BZfQ-",
+ 8,
+ 0xdeadbeef
+ },
+ /* tests a buffer that runs out while not encoding a UTF-7 sequence */
+ {
+ {'h','e','l','l','o',0},
+ -1,
+ 2,
+ "he",
+ 0,
+ ERROR_INSUFFICIENT_BUFFER
+ },
+ /* tests a buffer that runs out in the middle of encoding a UTF-7 sequence */
+ {
+ {0x4F60,0x597D,0},
+ -1,
+ 2,
+ "+T",
+ 0,
+ ERROR_INSUFFICIENT_BUFFER
+ }
+ };
+
+ struct mbstowcs_test
+ {
+ /* inputs */
+ char src[2048];
+ int srclen;
+ int dstlen;
+ /* expected outputs */
+ WCHAR dst[2048];
+ int len;
+ DWORD error;
+ };
+
+ struct mbstowcs_test mbstowcs_tests[] = {
+ /* tests which one-byte characters implicitly terminate a sequence */
+ /* also tests whether the unfinished byte pair is discarded or not */
+ /* also tests srclen > strlen(src) */
+ {
+ "+A\x01-+B\x02-+C\x03-+D\x04-+E\x05-+F\x06-+G\x07-+H\x08-+I\x09-+J"
+ "\x0A-+K\x0B-+L\x0C-+M\x0D-+N\x0E-+O\x0F-+P\x10-+Q\x11-+R\x12-+S"
+ "\x13-+T\x14-+U\x15-+V\x16-+W\x17-+X\x18-+Y\x19-+Z\x1A-+a\x1B-+b"
+ "\x1C-+c\x1D-+d\x1E-+e\x1F-+f\x20-+g\x21-+h\x22-+i\x23-+j\x24-+k"
+ "\x25-+l\x26-+m\x27-+n\x28-+o\x29-+p\x2A-+q\x2B-+r\x2C-+s\x2D-+t"
+ "\x2E-+u\x2F-+v\x30-+w\x31-+x\x32-+y\x33-+z\x34-+0\x35-+1\x36-+2"
+ "\x37-+3\x38-+4\x39-+5\x3A-+6\x3B-+7\x3C-+8\x3D-+9\x3E-++\x3F-+/"
+ "\x40-+A\x41-+B\x42-+C\x43-+D\x44-+E\x45-+F\x46-+G\x47-+H\x48-+I"
+ "\x49-+J\x4A-+K\x4B-+L\x4C-+M\x4D-+N\x4E-+O\x4F-+P\x50-+Q\x51-+R"
+ "\x52-+S\x53-+T\x54-+U\x55-+V\x56-+W\x57-+X\x58-+Y\x59-+Z\x5A-+a"
+ "\x5B-+b\x5C-+c\x5D-+d\x5E-+e\x5F-+f\x60-+g\x61-+h\x62-+i\x63-+j"
+ "\x64-+k\x65-+l\x66-+m\x67-+n\x68-+o\x69-+p\x6A-+q\x6B-+r\x6C-+s"
+ "\x6D-+t\x6E-+u\x6F-+v\x70-+w\x71-+x\x72-+y\x73-+z\x74-+0\x75-+1"
+ "\x76-+2\x77-+3\x78-+4\x79-+5\x7A-+6\x7B-+7\x7C-+8\x7D-+9\x7E-++"
+ "\x7F-+/\x80-+A\x81-+B\x82-+C\x83-+D\x84-+E\x85-+F\x86-+G\x87-+H"
+ "\x88-+I\x89-+J\x8A-+K\x8B-+L\x8C-+M\x8D-+N\x8E-+O\x8F-+P\x90-+Q"
+ "\x91-+R\x92-+S\x93-+T\x94-+U\x95-+V\x96-+W\x97-+X\x98-+Y\x99-+Z"
+ "\x9A-+a\x9B-+b\x9C-+c\x9D-+d\x9E-+e\x9F-+f\xA0-+g\xA1-+h\xA2-+i"
+ "\xA3-+j\xA4-+k\xA5-+l\xA6-+m\xA7-+n\xA8-+o\xA9-+p\xAA-+q\xAB-+r"
+ "\xAC-+s\xAD-+t\xAE-+u\xAF-+v\xB0-+w\xB1-+x\xB2-+y\xB3-+z\xB4-+0"
+ "\xB5-+1\xB6-+2\xB7-+3\xB8-+4\xB9-+5\xBA-+6\xBB-+7\xBC-+8\xBD-+9"
+ "\xBE-++\xBF-+/\xC0-+A\xC1-+B\xC2-+C\xC3-+D\xC4-+E\xC5-+F\xC6-+G"
+ "\xC7-+H\xC8-+I\xC9-+J\xCA-+K\xCB-+L\xCC-+M\xCD-+N\xCE-+O\xCF-+P"
+ "\xD0-+Q\xD1-+R\xD2-+S\xD3-+T\xD4-+U\xD5-+V\xD6-+W\xD7-+X\xD8-+Y"
+ "\xD9-+Z\xDA-+a\xDB-+b\xDC-+c\xDD-+d\xDE-+e\xDF-+f\xE0-+g\xE1-+h"
+ "\xE2-+i\xE3-+j\xE4-+k\xE5-+l\xE6-+m\xE7-+n\xE8-+o\xE9-+p\xEA-+q"
+ "\xEB-+r\xEC-+s\xED-+t\xEE-+u\xEF-+v\xF0-+w\xF1-+x\xF2-+y\xF3-+z"
+ "\xF4-+0\xF5-+1\xF6-+2\xF7-+3\xF8-+4\xF9-+5\xFA-+6\xFB-+7\xFC-+8"
+ "\xFD-+9\xFE-++\xFF-+A",
+ 1023,
+ 2047,
+ {0x0001,'-',0x0002,'-',0x0003,'-',0x0004,'-',0x0005,'-',0x0006,'-',
+ 0x0007,'-',0x0008,'-','\t','-','\n','-',0x000B,'-',0x000C,'-','\r',
+ '-',0x000E,'-',0x000F,'-',0x0010,'-',0x0011,'-',0x0012,'-',0x0013,
+ '-',0x0014,'-',0x0015,'-',0x0016,'-',0x0017,'-',0x0018,'-',0x0019,
+ '-',0x001A,'-',0x001B,'-',0x001C,'-',0x001D,'-',0x001E,'-',0x001F,
+ '-',' ','-','!','-','"','-','#','-','$','-','%','-','&','-','\'',
+ '-','(','-',')','-','*','-',',','-','-','.','-',':','-',';','-','<',
+ '-','=','-','>','-','?','-','@','-','[','-','\\','-',']','-','^',
+ '-','_','-','`','-','{','-','|','-','}','-','~','-',0x007F,'-',
+ 0x0080,'-',0x0081,'-',0xFC00,0x0082,'-',0x0083,'-',0x0084,'-',
+ 0x420C,0x0085,'-',0x0086,'-',0x4146,0x0087,'-',0x0088,'-',0x0089,
+ '-',0x1C82,0x008A,'-',0x008B,'-',0x008C,'-',0x4A2C,0x008D,'-',
+ 0x008E,'-',0xC34E,0x008F,'-',0x0090,'-',0x0091,'-',0x3D04,0x0092,
+ '-',0x0093,'-',0x0094,'-',0x524D,0x0095,'-',0x0096,'-',0x4556,
+ 0x0097,'-',0x0098,'-',0x0099,'-',0x5D86,0x009A,'-',0x009B,'-',
+ 0x009C,'-',0x5A6D,0x009D,'-',0x009E,'-',0xC75E,0x009F,'-',0x00A0,
+ '-',0x00A1,'-',0x7E08,0x00A2,'-',0x00A3,'-',0x00A4,'-',0x628E,
+ 0x00A5,'-',0x00A6,'-',0x4966,0x00A7,'-',0x00A8,'-',0x00A9,'-',
+ 0x9E8A,0x00AA,'-',0x00AB,'-',0x00AC,'-',0x6AAE,0x00AD,'-',0x00AE,
+ '-',0xCB6E,0x00AF,'-',0x00B0,'-',0x00B1,'-',0xBF0C,0x00B2,'-',
+ 0x00B3,'-',0x00B4,'-',0x72CF,0x00B5,'-',0x00B6,'-',0x4D76,0x00B7,
+ '-',0x00B8,'-',0x00B9,'-',0xDF8E,0x00BA,'-',0x00BB,'-',0x00BC,'-',
+ 0x7AEF,0x00BD,'-',0x00BE,'-',0xCF7E,0x00BF,'-',0x00C0,'-',0x00C1,
+ '-',0xFC00,0x00C2,'-',0x00C3,'-',0x00C4,'-',0x420C,0x00C5,'-',
+ 0x00C6,'-',0x4146,0x00C7,'-',0x00C8,'-',0x00C9,'-',0x1C82,0x00CA,
+ '-',0x00CB,'-',0x00CC,'-',0x4A2C,0x00CD,'-',0x00CE,'-',0xC34E,
+ 0x00CF,'-',0x00D0,'-',0x00D1,'-',0x3D04,0x00D2,'-',0x00D3,'-',
+ 0x00D4,'-',0x524D,0x00D5,'-',0x00D6,'-',0x4556,0x00D7,'-',0x00D8,
+ '-',0x00D9,'-',0x5D86,0x00DA,'-',0x00DB,'-',0x00DC,'-',0x5A6D,
+ 0x00DD,'-',0x00DE,'-',0xC75E,0x00DF,'-',0x00E0,'-',0x00E1,'-',
+ 0x7E08,0x00E2,'-',0x00E3,'-',0x00E4,'-',0x628E,0x00E5,'-',0x00E6,
+ '-',0x4966,0x00E7,'-',0x00E8,'-',0x00E9,'-',0x9E8A,0x00EA,'-',
+ 0x00EB,'-',0x00EC,'-',0x6AAE,0x00ED,'-',0x00EE,'-',0xCB6E,0x00EF,
+ '-',0x00F0,'-',0x00F1,'-',0xBF0C,0x00F2,'-',0x00F3,'-',0x00F4,'-',
+ 0x72CF,0x00F5,'-',0x00F6,'-',0x4D76,0x00F7,'-',0x00F8,'-',0x00F9,
+ '-',0xDF8E,0x00FA,'-',0x00FB,'-',0x00FC,'-',0x7AEF,0x00FD,'-',
+ 0x00FE,'-',0xCF7E,0x00FF,'-',0},
+ 430,
+ 0xdeadbeef
+ },
+ /* tests which one-byte characters remove stray + signs */
+ {
+ "+\x01-+\x02-+\x03-+\x04-+\x05-+\x06-+\x07-+\x08-+\x09-+\x0A-+\x0B-"
+ "+\x0C-+\x0D-+\x0E-+\x0F-+\x10-+\x11-+\x12-+\x13-+\x14-+\x15-+\x16-"
+ "+\x17-+\x18-+\x19-+\x1A-+\x1B-+\x1C-+\x1D-+\x1E-+\x1F-+\x20-+\x21-"
+ "+\x22-+\x23-+\x24-+\x25-+\x26-+\x27-+\x28-+\x29-+\x2A-+\x2B-+\x2C-"
+ "+\x2D-+\x2E-+\x2F-+\x30-+\x31-+\x32-+\x33-+\x34-+\x35-+\x36-+\x37-"
+ "+\x38-+\x39-+\x3A-+\x3B-+\x3C-+\x3D-+\x3E-+\x3F-+\x40-+\x41-+\x42-"
+ "+\x43-+\x44-+\x45-+\x46-+\x47-+\x48-+\x49-+\x4A-+\x4B-+\x4C-+\x4D-"
+ "+\x4E-+\x4F-+\x50-+\x51-+\x52-+\x53-+\x54-+\x55-+\x56-+\x57-+\x58-"
+ "+\x59-+\x5A-+\x5B-+\x5C-+\x5D-+\x5E-+\x5F-+\x60-+\x61-+\x62-+\x63-"
+ "+\x64-+\x65-+\x66-+\x67-+\x68-+\x69-+\x6A-+\x6B-+\x6C-+\x6D-+\x6E-"
+ "+\x6F-+\x70-+\x71-+\x72-+\x73-+\x74-+\x75-+\x76-+\x77-+\x78-+\x79-"
+ "+\x7A-+\x7B-+\x7C-+\x7D-+\x7E-+\x7F-+\x80-+\x81-+\x82-+\x83-+\x84-"
+ "+\x85-+\x86-+\x87-+\x88-+\x89-+\x8A-+\x8B-+\x8C-+\x8D-+\x8E-+\x8F-"
+ "+\x90-+\x91-+\x92-+\x93-+\x94-+\x95-+\x96-+\x97-+\x98-+\x99-+\x9A-"
+ "+\x9B-+\x9C-+\x9D-+\x9E-+\x9F-+\xA0-+\xA1-+\xA2-+\xA3-+\xA4-+\xA5-"
+ "+\xA6-+\xA7-+\xA8-+\xA9-+\xAA-+\xAB-+\xAC-+\xAD-+\xAE-+\xAF-+\xB0-"
+ "+\xB1-+\xB2-+\xB3-+\xB4-+\xB5-+\xB6-+\xB7-+\xB8-+\xB9-+\xBA-+\xBB-"
+ "+\xBC-+\xBD-+\xBE-+\xBF-+\xC0-+\xC1-+\xC2-+\xC3-+\xC4-+\xC5-+\xC6-"
+ "+\xC7-+\xC8-+\xC9-+\xCA-+\xCB-+\xCC-+\xCD-+\xCE-+\xCF-+\xD0-+\xD1-"
+ "+\xD2-+\xD3-+\xD4-+\xD5-+\xD6-+\xD7-+\xD8-+\xD9-+\xDA-+\xDB-+\xDC-"
+ "+\xDD-+\xDE-+\xDF-+\xE0-+\xE1-+\xE2-+\xE3-+\xE4-+\xE5-+\xE6-+\xE7-"
+ "+\xE8-+\xE9-+\xEA-+\xEB-+\xEC-+\xED-+\xEE-+\xEF-+\xF0-+\xF1-+\xF2-"
+ "+\xF3-+\xF4-+\xF5-+\xF6-+\xF7-+\xF8-+\xF9-+\xFA-+\xFB-+\xFC-+\xFD-"
+ "+\xFE-+\xFF-+",
+ 767,
+ 2047,
+ {0x0001,'-',0x0002,'-',0x0003,'-',0x0004,'-',0x0005,'-',0x0006,'-',
+ 0x0007,'-',0x0008,'-','\t','-','\n','-',0x000B,'-',0x000C,'-','\r',
+ '-',0x000E,'-',0x000F,'-',0x0010,'-',0x0011,'-',0x0012,'-',0x0013,
+ '-',0x0014,'-',0x0015,'-',0x0016,'-',0x0017,'-',0x0018,'-',0x0019,
+ '-',0x001A,'-',0x001B,'-',0x001C,'-',0x001D,'-',0x001E,'-',0x001F,
+ '-',' ','-','!','-','"','-','#','-','$','-','%','-','&','-','\'',
+ '-','(','-',')','-','*','-',',','-','+','-','.','-',':','-',';','-',
+ '<','-','=','-','>','-','?','-','@','-','[','-','\\','-',']','-',
+ '^','-','_','-','`','-','{','-','|','-','}','-','~','-',0x007F,'-',
+ 0x0080,'-',0x0081,'-',0x0082,'-',0x0083,'-',0x0084,'-',0x0085,'-',
+ 0x0086,'-',0x0087,'-',0x0088,'-',0x0089,'-',0x008A,'-',0x008B,'-',
+ 0x008C,'-',0x008D,'-',0x008E,'-',0x008F,'-',0x0090,'-',0x0091,'-',
+ 0x0092,'-',0x0093,'-',0x0094,'-',0x0095,'-',0x0096,'-',0x0097,'-',
+ 0x0098,'-',0x0099,'-',0x009A,'-',0x009B,'-',0x009C,'-',0x009D,'-',
+ 0x009E,'-',0x009F,'-',0x00A0,'-',0x00A1,'-',0x00A2,'-',0x00A3,'-',
+ 0x00A4,'-',0x00A5,'-',0x00A6,'-',0x00A7,'-',0x00A8,'-',0x00A9,'-',
+ 0x00AA,'-',0x00AB,'-',0x00AC,'-',0x00AD,'-',0x00AE,'-',0x00AF,'-',
+ 0x00B0,'-',0x00B1,'-',0x00B2,'-',0x00B3,'-',0x00B4,'-',0x00B5,'-',
+ 0x00B6,'-',0x00B7,'-',0x00B8,'-',0x00B9,'-',0x00BA,'-',0x00BB,'-',
+ 0x00BC,'-',0x00BD,'-',0x00BE,'-',0x00BF,'-',0x00C0,'-',0x00C1,'-',
+ 0x00C2,'-',0x00C3,'-',0x00C4,'-',0x00C5,'-',0x00C6,'-',0x00C7,'-',
+ 0x00C8,'-',0x00C9,'-',0x00CA,'-',0x00CB,'-',0x00CC,'-',0x00CD,'-',
+ 0x00CE,'-',0x00CF,'-',0x00D0,'-',0x00D1,'-',0x00D2,'-',0x00D3,'-',
+ 0x00D4,'-',0x00D5,'-',0x00D6,'-',0x00D7,'-',0x00D8,'-',0x00D9,'-',
+ 0x00DA,'-',0x00DB,'-',0x00DC,'-',0x00DD,'-',0x00DE,'-',0x00DF,'-',
+ 0x00E0,'-',0x00E1,'-',0x00E2,'-',0x00E3,'-',0x00E4,'-',0x00E5,'-',
+ 0x00E6,'-',0x00E7,'-',0x00E8,'-',0x00E9,'-',0x00EA,'-',0x00EB,'-',
+ 0x00EC,'-',0x00ED,'-',0x00EE,'-',0x00EF,'-',0x00F0,'-',0x00F1,'-',
+ 0x00F2,'-',0x00F3,'-',0x00F4,'-',0x00F5,'-',0x00F6,'-',0x00F7,'-',
+ 0x00F8,'-',0x00F9,'-',0x00FA,'-',0x00FB,'-',0x00FC,'-',0x00FD,'-',
+ 0x00FE,'-',0x00FF,'-',0},
+ 383,
+ 0xdeadbeef
+ },
+ /* tests srclen > strlen(src) */
+ {
+ "a\0b",
+ 4,
+ 2047,
+ {'a',0,'b',0},
+ 4,
+ 0xdeadbeef
+ },
+ /* tests srclen < strlen(src) outside of a UTF-7 sequence */
+ {
+ "hello",
+ 2,
+ 2047,
+ {'h','e'},
+ 2,
+ 0xdeadbeef
+ },
+ /* tests srclen < strlen(src) inside of a UTF-7 sequence */
+ {
+ "+T2BZfQ-",
+ 4,
+ 2047,
+ {0x4F60},
+ 1,
+ 0xdeadbeef
+ },
+ /* tests a buffer that runs out while not decoding a UTF-7 sequence */
+ {
+ "hello",
+ -1,
+ 2,
+ {'h','e'},
+ 0,
+ ERROR_INSUFFICIENT_BUFFER
+ },
+ /* tests a buffer that runs out in the middle of decoding a UTF-7 sequence */
+ {
+ "+T2BZfQ-",
+ -1,
+ 1,
+ {0x4F60},
+ 0,
+ ERROR_INSUFFICIENT_BUFFER
+ }
+ };
+
+ int i;
+
+ for (i = 0; i < sizeof(utf16_to_utf7_tests) / sizeof(struct utf16_to_utf7_test); i++)
+ {
+ char c_buffer[32];
+ WCHAR w_buffer[32];
+ int len;
+
+ /* null-terminate the buffers */
+ c_buffer[sizeof(c_buffer) - 1] = 0;
+ w_buffer[sizeof(w_buffer) / sizeof(WCHAR) - 1] = 0;
+
+ /* test string conversion with srclen=-1 */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -1, c_buffer, sizeof(c_buffer), NULL, NULL);
+ ok(len == utf16_to_utf7_tests[i].utf7_len &&
+ strcmp(c_buffer, utf16_to_utf7_tests[i].utf7) == 0 &&
+ c_buffer[len] == '#',
+ "utf16_to_utf7_test failure i=%i dst=\"%s\" len=%i\n", i, c_buffer, len);
+
+ /* test string conversion with srclen=-2 */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -2, c_buffer, sizeof(c_buffer), NULL, NULL);
+ ok(len == utf16_to_utf7_tests[i].utf7_len &&
+ strcmp(c_buffer, utf16_to_utf7_tests[i].utf7) == 0 &&
+ c_buffer[len] == '#',
+ "utf16_to_utf7_test failure i=%i dst=\"%s\" len=%i\n", i, c_buffer, len);
+
+ /* test string conversion with dstlen=len-1 */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ SetLastError(0);
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -1, c_buffer, utf16_to_utf7_tests[i].utf7_len - 1, NULL, NULL);
+ ok(len == 0 &&
+ memcmp(c_buffer, utf16_to_utf7_tests[i].utf7, utf16_to_utf7_tests[i].utf7_len - 1) == 0 &&
+ c_buffer[utf16_to_utf7_tests[i].utf7_len - 1] == '#',
+ "utf16_to_utf7_test failure i=%i dst=\"%s\" len=%i\n", i, c_buffer, len);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error=%x\n", GetLastError());
+
+ /* test string conversion with dstlen=len */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -1, c_buffer, utf16_to_utf7_tests[i].utf7_len, NULL, NULL);
+ ok(len == utf16_to_utf7_tests[i].utf7_len &&
+ strcmp(c_buffer, utf16_to_utf7_tests[i].utf7) == 0 &&
+ c_buffer[len] == '#',
+ "utf16_to_utf7_test failure i=%i dst=\"%s\" len=%i\n", i, c_buffer, len);
+
+ /* test string conversion with dstlen=len+1 */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -1, c_buffer, utf16_to_utf7_tests[i].utf7_len + 1, NULL, NULL);
+ ok(len == utf16_to_utf7_tests[i].utf7_len &&
+ strcmp(c_buffer, utf16_to_utf7_tests[i].utf7) == 0 &&
+ c_buffer[len] == '#',
+ "utf16_to_utf7_test failure i=%i dst=\"%s\" len=%i\n", i, c_buffer, len);
+
+ /* test dry run with dst=NULL and dstlen=0 */
+ memset(c_buffer, '#', sizeof(c_buffer));
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -1, NULL, 0, NULL, NULL);
+ ok(len == utf16_to_utf7_tests[i].utf7_len &&
+ c_buffer[0] == '#',
+ "utf16_to_utf7_test failure i=%i len=%i\n", i, len);
+
+ /* test dry run with dst!=NULL and dstlen=0 */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ len = WideCharToMultiByte(CP_UTF7, 0, utf16_to_utf7_tests[i].utf16, -1, c_buffer, 0, NULL, NULL);
+ ok(len == utf16_to_utf7_tests[i].utf7_len &&
+ c_buffer[0] == '#',
+ "utf16_to_utf7_test failure i=%i len=%i\n", i, len);
+
+ /* all simple utf16-to-utf7 tests can be reversed to make utf7-to-utf16 tests */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf16_to_utf7_tests[i].utf7, -1, w_buffer, sizeof(w_buffer) / sizeof(WCHAR));
+ ok(len == utf16_to_utf7_tests[i].utf16_len &&
+ memcmp(w_buffer, utf16_to_utf7_tests[i].utf16, len * sizeof(WCHAR)) == 0 &&
+ w_buffer[len] == 0x2323,
+ "utf16_to_utf7_test failure i=%i dst=%s len=%i\n", i, wine_dbgstr_w(w_buffer), len);
+ }
+
+ for (i = 0; i < sizeof(utf7_to_utf16_tests) / sizeof(struct utf7_to_utf16_test); i++)
+ {
+ WCHAR w_buffer[32];
+ int len;
+
+ /* null-terminate the buffer */
+ w_buffer[sizeof(w_buffer) / sizeof(WCHAR) - 1] = 0;
+
+ /* test string conversion with srclen=-1 */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -1, w_buffer, sizeof(w_buffer) / sizeof(WCHAR));
+ ok(len == utf7_to_utf16_tests[i].utf16_len &&
+ winetest_strcmpW(w_buffer, utf7_to_utf16_tests[i].utf16) == 0 &&
+ w_buffer[len] == 0x2323,
+ "utf7_to_utf16_test failure i=%i dst=%s len=%i\n", i, wine_dbgstr_w(w_buffer), len);
+
+ /* test string conversion with srclen=-2 */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -2, w_buffer, sizeof(w_buffer) / sizeof(WCHAR));
+ ok(len == utf7_to_utf16_tests[i].utf16_len &&
+ winetest_strcmpW(w_buffer, utf7_to_utf16_tests[i].utf16) == 0 &&
+ w_buffer[len] == 0x2323,
+ "utf7_to_utf16_test failure i=%i dst=%s len=%i\n", i, wine_dbgstr_w(w_buffer), len);
+
+ /* test string conversion with dstlen=len-1 */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ SetLastError(0);
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -1, w_buffer, utf7_to_utf16_tests[i].utf16_len - 1);
+ ok(len == 0 &&
+ memcmp(w_buffer, utf7_to_utf16_tests[i].utf16, (utf7_to_utf16_tests[i].utf16_len - 1) * sizeof(WCHAR)) == 0 &&
+ w_buffer[utf7_to_utf16_tests[i].utf16_len - 1] == 0x2323,
+ "utf7_to_utf16_test failure i=%i dst=%s len=%i\n", i, wine_dbgstr_w(w_buffer), len);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error=%x\n", GetLastError());
+
+ /* test string conversion with dstlen=len */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -1, w_buffer, utf7_to_utf16_tests[i].utf16_len);
+ ok(len == utf7_to_utf16_tests[i].utf16_len &&
+ winetest_strcmpW(w_buffer, utf7_to_utf16_tests[i].utf16) == 0 &&
+ w_buffer[len] == 0x2323,
+ "utf7_to_utf16_test failure i=%i dst=%s len=%i\n", i, wine_dbgstr_w(w_buffer), len);
+
+ /* test string conversion with dstlen=len+1 */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -1, w_buffer, utf7_to_utf16_tests[i].utf16_len + 1);
+ ok(len == utf7_to_utf16_tests[i].utf16_len &&
+ winetest_strcmpW(w_buffer, utf7_to_utf16_tests[i].utf16) == 0 &&
+ w_buffer[len] == 0x2323,
+ "utf7_to_utf16_test failure i=%i dst=%s len=%i\n", i, wine_dbgstr_w(w_buffer), len);
+
+ /* test dry run with dst=NULL and dstlen=0 */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -1, NULL, 0);
+ ok(len == utf7_to_utf16_tests[i].utf16_len &&
+ w_buffer[0] == 0x2323,
+ "utf7_to_utf16_test failure i=%i len=%i\n", i, len);
+
+ /* test dry run with dst!=NULL and dstlen=0 */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_UTF7, 0, utf7_to_utf16_tests[i].utf7, -1, w_buffer, 0);
+ ok(len == utf7_to_utf16_tests[i].utf16_len &&
+ w_buffer[0] == 0x2323,
+ "utf7_to_utf16_test failure i=%i len=%i\n", i, len);
+ }
+
+ for (i = 0; i < sizeof(wcstombs_tests) / sizeof(struct wcstombs_test); i++)
+ {
+ char c_buffer[2048];
+ int len;
+
+ /* null-terminate the buffer */
+ c_buffer[sizeof(c_buffer) - 1] = 0;
+
+ /* run a complicated utf16-to-utf7 test */
+ memset(c_buffer, '#', sizeof(c_buffer) - 1);
+ SetLastError(0xdeadbeef);
+ len = WideCharToMultiByte(CP_UTF7, 0, wcstombs_tests[i].src, wcstombs_tests[i].srclen, c_buffer, wcstombs_tests[i].dstlen, NULL, NULL);
+ ok(len == wcstombs_tests[i].len &&
+ memcmp(c_buffer, wcstombs_tests[i].dst, len ? len : wcstombs_tests[i].dstlen) == 0 &&
+ c_buffer[len ? len : wcstombs_tests[i].dstlen] == '#',
+ "wcstombs_test failure i=%i len=%i dst=\"%s\"\n", i, len, c_buffer);
+ ok(GetLastError() == wcstombs_tests[i].error, "error=%x\n", GetLastError());
+ }
+
+ for (i = 0; i < sizeof(mbstowcs_tests) / sizeof(struct mbstowcs_test); i++)
+ {
+ WCHAR w_buffer[2048];
+ int len;
+
+ /* null-terminate the buffer */
+ w_buffer[sizeof(w_buffer) / sizeof(WCHAR) - 1] = 0;
+
+ /* run a complicated utf7-to-utf16 test */
+ memset(w_buffer, '#', sizeof(w_buffer) - sizeof(WCHAR));
+ SetLastError(0xdeadbeef);
+ len = MultiByteToWideChar(CP_UTF7, 0, mbstowcs_tests[i].src, mbstowcs_tests[i].srclen, w_buffer, mbstowcs_tests[i].dstlen);
+ ok(len == mbstowcs_tests[i].len &&
+ memcmp(w_buffer, mbstowcs_tests[i].dst, (len ? len : mbstowcs_tests[i].dstlen) * sizeof(WCHAR)) == 0 &&
+ w_buffer[len ? len : mbstowcs_tests[i].dstlen] == 0x2323,
+ "mbstowcs_test failure i=%i len=%i dst=%s\n", i, len, wine_dbgstr_w(w_buffer));
+ ok(GetLastError() == mbstowcs_tests[i].error, "error=%x\n", GetLastError());
+ }
+}
+
static void test_undefined_byte_char(void)
{
static const struct tag_testset {
@@ -618,6 +1303,8 @@ START_TEST(codepage)
test_string_conversion(NULL);
test_string_conversion(&bUsedDefaultChar);
+ test_utf7_string_conversion();
+
test_undefined_byte_char();
test_threadcp();
}
--
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