Fix packet format and support Unicode 32

Fixes a packet in the format send between xrdp and chansrv.
UTF-16 surrogate pairs sent from the client are remapped
to full unicode characters.
This commit is contained in:
matt335672 2024-03-26 10:16:09 +00:00 committed by sefler
parent 20b90c1098
commit 6da58825fe
3 changed files with 62 additions and 9 deletions

View File

@ -2115,8 +2115,9 @@ xrdp_mm_send_unicode_to_chansrv(struct xrdp_mm *self,
return 1;
}
out_uint32_le(s, 0); /* version */
out_uint32_le(s, 8 + 4 + 4 + 4);
out_uint32_le(s, 24); /* size */
out_uint32_le(s, 21); /* msg id */
out_uint32_le(s, 16); /* size */
out_uint32_le(s, key_down);
out_uint32_le(s, unicode);
s_mark_end(s);

View File

@ -547,6 +547,9 @@ struct xrdp_wm
int caps_lock;
int scroll_lock;
int num_lock;
/* Unicode input */
int last_high_surrogate_key_up;
int last_high_surrogate_key_down;
/* client info */
struct xrdp_client_info *client_info;
/* session log */

View File

@ -28,6 +28,7 @@
#include "ms-rdpbcgr.h"
#include "log.h"
#include "string_calls.h"
#include "unicode_defines.h"
/*****************************************************************************/
static void
@ -1675,17 +1676,65 @@ xrdp_wm_key_sync(struct xrdp_wm *self, int device_flags, int key_flags)
}
/*****************************************************************************/
static int
xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t unicode)
/**
* Takes a stream of UTF-16 characters and maps then to Unicode characters
*/
static char32_t
get_unicode_character(struct xrdp_wm *self, int device_flags, char16_t c16)
{
char32_t c32 = 0;
int *high_ptr;
if (device_flags & KBD_FLAG_UP)
{
high_ptr = &self->last_high_surrogate_key_up;
}
else
{
high_ptr = &self->last_high_surrogate_key_down;
}
if (IS_HIGH_SURROGATE(c16))
{
// Record high surrogate for next time
*high_ptr = c16;
}
else if (IS_LOW_SURROGATE(c16))
{
// If last character was a high surrogate, we can use it
if (*high_ptr != 0)
{
c32 = C32_FROM_SURROGATE_PAIR(c16, *high_ptr);
*high_ptr = 0;
}
}
else
{
// Character maps straight across
c32 = c16;
*high_ptr = 0;
}
return c32;
}
/*****************************************************************************/
static int
xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char16_t c16)
{
char32_t c32 = get_unicode_character(self, device_flags, c16);
if (c32 == 0)
{
return 0;
}
#ifdef XRDP_IBUS
// Test code for ibus Unicode forwarding
if (self->mm->chan_trans != NULL &&
self->mm->chan_trans->status == TRANS_STATUS_UP)
{
xrdp_mm_send_unicode_to_chansrv(self->mm,
(device_flags & KBD_FLAG_UP) == 0,
unicode);
!(device_flags & KBD_FLAG_UP), c32);
return 0;
}
#endif
@ -1694,7 +1743,7 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t unicode)
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{
if (unicode == self->keymap.keys_noshift[index].chr)
if (c32 == self->keymap.keys_noshift[index].chr)
{
xrdp_wm_key(self, device_flags, index - XR_MIN_KEY_CODE);
return 0;
@ -1703,7 +1752,7 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t unicode)
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{
if (unicode == self->keymap.keys_shift[index].chr)
if (c32 == self->keymap.keys_shift[index].chr)
{
if (device_flags & KBD_FLAG_UP)
{
@ -1721,7 +1770,7 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t unicode)
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{
if (unicode == self->keymap.keys_altgr[index].chr)
if (c32 == self->keymap.keys_altgr[index].chr)
{
if (device_flags & KBD_FLAG_UP)
{
@ -1741,7 +1790,7 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t unicode)
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{
if (unicode == self->keymap.keys_shiftaltgr[index].chr)
if (c32 == self->keymap.keys_shiftaltgr[index].chr)
{
if (device_flags & KBD_FLAG_UP)
{