Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/imm32/imm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 28eb00f355..96a11abba5 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -119,8 +119,15 @@ static CRITICAL_SECTION_DEBUG critsect_debug = static CRITICAL_SECTION threaddata_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; static BOOL disable_ime;
-#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE) -#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE) +static inline BOOL is_himc_ime_unicode(const InputContextData *data) +{ + return !!(data->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE); +} + +static inline BOOL is_kbd_ime_unicode(const ImmHkl *hkl) +{ + return !!(hkl->imeInfo.fdwProperty & IME_PROP_UNICODE); +}
static BOOL IMM_DestroyContext(HIMC hIMC); static InputContextData* get_imc_data(HIMC hIMC);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/imm32/imm.c | 28 +++++++++++++++++----------- dlls/imm32/tests/imm32.c | 25 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 96a11abba5..a385d884cb 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1206,23 +1206,29 @@ BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
/* Helpers for the GetCompositionString functions */
-static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen, - BOOL unicode ) +/* Source encoding is defined by context, source length is always given in respective characters. Destination buffer + length is always in bytes. */ +static INT CopyCompStringIMEtoClient(const InputContextData *data, const void *src, INT src_len, void *dst, + INT dst_len, BOOL unicode) { - INT rc; + int char_size = unicode ? sizeof(WCHAR) : sizeof(char); + INT ret;
- if (is_himc_ime_unicode(data) && !unicode) - rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL); - else if (!is_himc_ime_unicode(data) && unicode) - rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR); + if (is_himc_ime_unicode(data) ^ unicode) + { + if (unicode) + ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len); + else + ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL); + ret *= char_size; + } else { - int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR); - memcpy( target, source, min(slen,tlen)*dlen); - rc = slen*dlen; + ret = min(src_len * char_size, dst_len); + memcpy(dst, src, ret); }
- return rc; + return ret; }
static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen, diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index ee1aeb3965..d15fa9c9ff 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -448,6 +448,31 @@ static void test_ImmGetCompositionString(void) ok(len*sizeof(WCHAR)==wlen,"GCS_COMPATTR(W) not returning correct count\n"); len = ImmGetCompositionStringA(imc, GCS_COMPATTR, NULL, 0); ok(len==alen,"GCS_COMPATTR(A) not returning correct count\n"); + + /* Get strings with exactly matching buffer sizes. */ + memset(wstring, 0x1a, sizeof(wstring)); + memset(cstring, 0x1a, sizeof(cstring)); + + len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen); + ok(len == alen, "Unexpected length %d.\n", len); + ok(cstring[alen] == 0x1a, "Unexpected buffer contents.\n"); + + len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen); + ok(len == wlen, "Unexpected length %d.\n", len); + ok(wstring[wlen/sizeof(WCHAR)] == 0x1a1a, "Unexpected buffer contents.\n"); + + /* Get strings with exactly smaller buffer sizes. */ + memset(wstring, 0x1a, sizeof(wstring)); + memset(cstring, 0x1a, sizeof(cstring)); + + /* Returns 0 but still fills buffer. */ + len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen - 1); + ok(!len, "Unexpected length %d.\n", len); + ok(cstring[0] == 'w', "Unexpected buffer contents %s.\n", cstring); + + len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen - 1); + ok(len == wlen - 1, "Unexpected length %d.\n", len); + ok(!memcmp(wstring, string, wlen - 1), "Unexpected buffer contents.\n"); } else win_skip("Composition string isn't available\n");
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/imm32/imm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index a385d884cb..948ef780f6 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -1217,7 +1217,7 @@ static INT CopyCompStringIMEtoClient(const InputContextData *data, const void *s if (is_himc_ime_unicode(data) ^ unicode) { if (unicode) - ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len); + ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len / sizeof(WCHAR)); else ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL); ret *= char_size;