Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package xrdp for openSUSE:Factory checked in 
at 2023-11-02 20:21:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xrdp (Old)
 and      /work/SRC/openSUSE:Factory/.xrdp.new.17445 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xrdp"

Thu Nov  2 20:21:59 2023 rev:54 rq:1121738 version:0.9.23.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/xrdp/xrdp.changes        2023-08-08 
15:55:29.997205626 +0200
+++ /work/SRC/openSUSE:Factory/.xrdp.new.17445/xrdp.changes     2023-11-02 
20:22:13.145489687 +0100
@@ -1,0 +2,22 @@
+Wed Oct 18 09:23:35 UTC 2023 - Dominique Leuenberger <[email protected]>
+
+- Update to version 0.9.23.1:
+  + Security fix: Unchecked access to font glyph info
+    (CVE-2023-42822).
+- Changes from version 0.9.23:
+  + General announcement: Running xrdp and xrdp-sesman on separate
+    hosts is still supported by this release, but is now
+    deprecated. This is not secure. A future v1.0 release will
+    replace the TCP socket used between these processes with a Unix
+    Domain Socket, and then cross-host running will not be
+    possible.
+  + Security fix: Improper handling of session establishment errors
+    allows bypassing OS-level session restrictions
+    (CVE-2023-40184).
+  + Bug fixes:
+    - Environment variables set by PAM modules are no longer
+      restricted to around 250 characters.
+    - X11 clipboard clients now no longer hang when requesting a
+      clipboard format which isn't available.
+
+-------------------------------------------------------------------

Old:
----
  xrdp-0.9.22.1.tar.gz
  xrdp-0.9.22.1.tar.gz.asc

New:
----
  xrdp-0.9.23.1.tar.gz
  xrdp-0.9.23.1.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xrdp.spec ++++++
--- /var/tmp/diff_new_pack.jJlcZm/_old  2023-11-02 20:22:13.981520450 +0100
+++ /var/tmp/diff_new_pack.jJlcZm/_new  2023-11-02 20:22:13.981520450 +0100
@@ -22,7 +22,7 @@
 %endif
 
 Name:           xrdp
-Version:        0.9.22.1
+Version:        0.9.23.1
 Release:        0
 Summary:        Remote desktop protocol (RDP) server
 License:        Apache-2.0 AND GPL-2.0-or-later

++++++ xrdp-0.9.22.1.tar.gz -> xrdp-0.9.23.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/NEWS.md new/xrdp-0.9.23.1/NEWS.md
--- old/xrdp-0.9.22.1/NEWS.md   2023-05-23 02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/NEWS.md   2023-09-27 19:59:31.000000000 +0200
@@ -1,10 +1,53 @@
+# Release notes for xrdp v0.9.23.1 (2023/09/27)
+
+This is a security fix release for CVE-2023-42822. This update is recommended 
for all xrdp users.
+
+## Security fixes
+
+* [CVE-2023-42822: Unchecked access to font glyph 
info](https://www.cve.org/CVERecord?id=CVE-2023-42822)
+
+## Bug fixes
+No bug fixes other than the above security fix in this release.
+
+## New features
+No new features in this release.
+
+## Internal changes
+* cppcheck install script no longer installs z3 for cppcheck >= 2.8 (#2782)
+
+-----------------------
+
+# Release notes for xrdp v0.9.23 (2023/08/31)
+
+## General announcements
+* Running xrdp and xrdp-sesman on separate hosts is still supported by this 
release, but is now deprecated. This is not secure. A future v1.0 release will 
replace the TCP socket used between these processes with a Unix Domain Socket, 
and then cross-host running will not be possible.
+
+## Security fixes
+* [CVE-2023-40184: Improper handling of session establishment errors allows 
bypassing OS-level session 
restrictions](https://www.cve.org/CVERecord?id=CVE-2023-40184) (Reported by 
[@gafusss](https://github.com/gafusss))
+
+## Bug fixes
+* Environment variables set by PAM modules are no longer restricted to around 
250 characters (#2712)
+* X11 clipboard clients now no longer hang when requesting a clipboard format 
which isn't available (#2767)
+
+## New features
+No new features in this release.
+
+## Internal changes
+* Introduce release tarball generation script (#2703)
+* cppcheck version used for CI bumped to 2.11 (#2738)
+
+## Known issues
+* On-the-fly resolution change requires the Microsoft Store version of Remote 
Desktop client but sometimes crashes on connect (#1869)
+* xrdp's login dialog is not relocated at the center of the new resolution 
after on-the-fly resolution change happens (#1867)
+
+-----------------------
 # Release notes for xrdp v0.9.22.1 (2023/05/23)
 
 This release is just a re-packing of source code tarball since v0.9.22 tarball 
includes invalid source code (#2687).
 
 See [v0.9.22 release 
note](https://github.com/neutrinolabs/xrdp/releases/tag/v0.9.22) for functional 
changes since v0.9.22.1 is what v0.9.22 should be.
 
-Thanks to [@morgancoxuk](https://github.com/morgancoxuk) and 
[bsmojver](https://github.com/bsmojver) for reporting and testing!
+Thanks to [@morgancoxuk](https://github.com/morgancoxuk) and 
[@bsmojver](https://github.com/bsmojver) for reporting and testing!
 
 ## References
 * https://github.com/neutrinolabs/xrdp/issues/2687
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/configure new/xrdp-0.9.23.1/configure
--- old/xrdp-0.9.22.1/configure 2023-05-23 02:19:17.000000000 +0200
+++ new/xrdp-0.9.23.1/configure 2023-09-27 19:59:54.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for xrdp 0.9.22.1.
+# Generated by GNU Autoconf 2.71 for xrdp 0.9.23.1.
 #
 # Report bugs to <[email protected]>.
 #
@@ -621,8 +621,8 @@
 # Identity of this package.
 PACKAGE_NAME='xrdp'
 PACKAGE_TARNAME='xrdp'
-PACKAGE_VERSION='0.9.22.1'
-PACKAGE_STRING='xrdp 0.9.22.1'
+PACKAGE_VERSION='0.9.23.1'
+PACKAGE_STRING='xrdp 0.9.23.1'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 
@@ -1483,7 +1483,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures xrdp 0.9.22.1 to adapt to many kinds of systems.
+\`configure' configures xrdp 0.9.23.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1558,7 +1558,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xrdp 0.9.22.1:";;
+     short | recursive ) echo "Configuration of xrdp 0.9.23.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1744,7 +1744,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-xrdp configure 0.9.22.1
+xrdp configure 0.9.23.1
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2000,7 +2000,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by xrdp $as_me 0.9.22.1, which was
+It was created by xrdp $as_me 0.9.23.1, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3271,7 +3271,7 @@
 
 # Define the identity of the package.
  PACKAGE='xrdp'
- VERSION='0.9.22.1'
+ VERSION='0.9.23.1'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -16600,7 +16600,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by xrdp $as_me 0.9.22.1, which was
+This file was extended by xrdp $as_me 0.9.23.1, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16668,7 +16668,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-xrdp config.status 0.9.22.1
+xrdp config.status 0.9.23.1
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/configure.ac 
new/xrdp-0.9.23.1/configure.ac
--- old/xrdp-0.9.22.1/configure.ac      2023-05-23 02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/configure.ac      2023-09-27 19:59:31.000000000 +0200
@@ -1,7 +1,7 @@
 # Process this file with autoconf to produce a configure script
 
 AC_PREREQ(2.65)
-AC_INIT([xrdp], [0.9.22.1], [[email protected]])
+AC_INIT([xrdp], [0.9.23.1], [[email protected]])
 AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
 AM_INIT_AUTOMAKE([1.7.2 foreign])
 AC_CONFIG_MACRO_DIR([m4])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/librfxcodec/tests/rfxencode.c 
new/xrdp-0.9.23.1/librfxcodec/tests/rfxencode.c
--- old/xrdp-0.9.22.1/librfxcodec/tests/rfxencode.c     2023-05-23 
02:18:52.000000000 +0200
+++ new/xrdp-0.9.23.1/librfxcodec/tests/rfxencode.c     2023-09-27 
19:59:34.000000000 +0200
@@ -170,7 +170,7 @@
     char *out_data;
     char *bmp_data;
     int out_fd;
-    int out_bytes;
+    int out_bytes = 0;
     int error;
     int index;
     int index_x;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/sesman/chansrv/clipboard.c 
new/xrdp-0.9.23.1/sesman/chansrv/clipboard.c
--- old/xrdp-0.9.22.1/sesman/chansrv/clipboard.c        2023-05-23 
02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/sesman/chansrv/clipboard.c        2023-09-27 
19:59:31.000000000 +0200
@@ -179,6 +179,7 @@
 #include "xcommon.h"
 #include "chansrv_fuse.h"
 #include "ms-rdpeclip.h"
+#include "xrdp_constants.h"
 
 static char g_bmp_image_header[] =
 {
@@ -245,10 +246,22 @@
 static int g_formatIds[16];
 static int g_num_formatIds = 0;
 
-static int g_file_format_id = -1;
+/* Format ID assigned to "FileGroupDescriptorW" by the client */
+static int g_file_group_descriptor_format_id = -1;
 
 static char g_last_atom_name[256] = "";
 
+/*
+ * Values for the named formats we send to the client in
+ * a Format List PDU
+ */
+
+enum
+{
+    CB_FORMAT_FILE_GROUP_DESCRIPTOR = 0xc0bc
+};
+
+
 /*****************************************************************************/
 static char *
 get_atom_text(Atom atom)
@@ -646,7 +659,7 @@
             case XRDP_CB_FILE:
                 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: 
XRDP_CB_FILE");
                 /* canned response for "file" */
-                out_uint32_le(s, 0x0000c0bc);
+                out_uint32_le(s, CB_FORMAT_FILE_GROUP_DESCRIPTOR);
                 clipboard_out_unicode(s, "FileGroupDescriptorW", 21);
                 out_uint32_le(s, 0x0000c0ba);
                 clipboard_out_unicode(s, "FileContents", 13);
@@ -690,7 +703,7 @@
             case XRDP_CB_FILE:
                 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: 
XRDP_CB_FILE");
                 /* canned response for "file" */
-                out_uint32_le(s, 0x0000c0bc);
+                out_uint32_le(s, CB_FORMAT_FILE_GROUP_DESCRIPTOR);
                 out_uint8p(s, windows_native_format, 
sizeof(windows_native_format));
                 out_uint32_le(s, 0x0000c0ba);
                 out_uint8p(s, windows_native_format, 
sizeof(windows_native_format));
@@ -1028,11 +1041,11 @@
             LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: max 
formats");
         }
 
-        /* format id for file copy copy seems to keep changing */
-        /* seen 0x0000c0c8, 0x0000c0ed */
+        /* format id for file copy copy is dynamic and announced by the
+         * client */
         if (g_strcmp(desc, "FileGroupDescriptorW") == 0)
         {
-            g_file_format_id = formatId;
+            g_file_group_descriptor_format_id = formatId;
         }
     }
 
@@ -1100,48 +1113,48 @@
     in_uint32_le(s, requestedFormatId);
     switch (requestedFormatId)
     {
-        case CB_FORMAT_FILE: /* 0xC0BC */
+        case CB_FORMAT_FILE_GROUP_DESCRIPTOR:
             if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_FILE) && 
g_clip_s2c.converted)
             {
-                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_FILE");
+                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_FILE_GROUP_DESCRIPTOR");
                 clipboard_send_data_response(XRDP_CB_FILE, g_clip_s2c.data,
                                              g_clip_s2c.total_bytes);
             }
             else
             {
-                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_FILE, "
+                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_FILE_GROUP_DESCRIPTOR, "
                           "calling XConvertSelection to g_utf8_atom");
                 g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE;
                 XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type,
                                   g_clip_property_atom, g_wnd, CurrentTime);
             }
             break;
-        case CB_FORMAT_DIB: /* 0x0008 */
+        case CF_DIB:
             if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_BITMAP) && 
g_clip_s2c.converted)
             {
-                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_DIB");
+                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CF_DIB");
                 clipboard_send_data_response(XRDP_CB_BITMAP, g_clip_s2c.data,
                                              g_clip_s2c.total_bytes);
             }
             else
             {
-                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_DIB, "
+                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CF_DIB, "
                           "calling XConvertSelection to g_image_bmp_atom");
                 g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP;
                 XConvertSelection(g_display, g_clipboard_atom, 
g_image_bmp_atom,
                                   g_clip_property_atom, g_wnd, CurrentTime);
             }
             break;
-        case CB_FORMAT_UNICODETEXT: /* 0x000D */
+        case CF_UNICODETEXT:
             if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_TEXT) && 
g_clip_s2c.converted)
             {
-                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_UNICODETEXT");
+                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CF_UNICODETEXT");
                 clipboard_send_data_response(XRDP_CB_TEXT, g_clip_s2c.data,
                                              g_clip_s2c.total_bytes);
             }
             else
             {
-                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CB_FORMAT_UNICODETEXT, "
+                LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: 
CF_UNICODETEXT, "
                           "calling XConvertSelection to g_utf8_atom");
                 g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT;
                 XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
@@ -1157,12 +1170,15 @@
     return 0;
 }
 
-/*****************************************************************************/
-/* client to server */
-/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
-   processing of the CB_FORMAT_DATA_REQUEST was successful; if processing
-   was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
-   clipboard data. */
+/**************************************************************************//**
+ * Process a CB_FORMAT_DATA_RESPONSE for an X client requesting an image
+ *
+ * @param s Stream containing CLIPRDR_FILELIST ([MS-RDPECLIP])
+ * @param clip_msg_status msgFlags from Clipboard PDU Header
+ * @param clip_msg_len dataLen from Clipboard PDU Header
+ *
+ * @return Status
+ */
 static int
 clipboard_process_data_response_for_image(struct stream *s,
         int clip_msg_status,
@@ -1289,6 +1305,90 @@
     return rv;
 }
 
+/**************************************************************************//**
+ * Process a CB_FORMAT_DATA_RESPONSE for an X client requesting text
+ *
+ * @param s Stream containing CLIPRDR_FILELIST ([MS-RDPECLIP])
+ * @param clip_msg_status msgFlags from Clipboard PDU Header
+ * @param clip_msg_len dataLen from Clipboard PDU Header
+ *
+ * @return Status
+ */
+static int
+clipboard_process_data_response_for_text(struct stream *s,
+        int clip_msg_status,
+        int clip_msg_len)
+{
+    XSelectionRequestEvent *lxev = &g_saved_selection_req_event;
+    twchar *wtext;
+    twchar wchr;
+    int len;
+    int index;
+    int byte_count;
+
+    LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_text: ");
+    len = (int)(s->end - s->p);
+    if (len < 1)
+    {
+        len = 0;
+    }
+    byte_count = ((len / 2) + 1) * sizeof(twchar);
+    wtext = (twchar *) g_malloc(byte_count, 0);
+    if (wtext == 0)
+    {
+        LOG(LOG_LEVEL_ERROR, "Can't allocate %d bytes for text clip response",
+            byte_count);
+
+        clipboard_refuse_selection(lxev);
+    }
+    else
+    {
+        index = 0;
+        while (s_check_rem(s, 2))
+        {
+            in_uint16_le(s, wchr);
+            wtext[index] = wchr;
+            if (wchr == 0)
+            {
+                break;
+            }
+            index++;
+        }
+        wtext[index] = 0;
+        g_free(g_clip_c2s.data);
+        g_clip_c2s.data = 0;
+        g_clip_c2s.total_bytes = 0;
+        len = g_wcstombs(0, wtext, 0);
+        if (len < 0)
+        {
+            LOG(LOG_LEVEL_ERROR,
+                "Received malformed Unicode paste text from client");
+            clipboard_refuse_selection(lxev);
+        }
+        else
+        {
+            byte_count = len + 16;
+            g_clip_c2s.data = (char *) g_malloc(byte_count, 0);
+            if (g_clip_c2s.data == 0)
+            {
+                LOG(LOG_LEVEL_ERROR,
+                    "Can't allocate %d bytes for text clip response",
+                    byte_count);
+                clipboard_refuse_selection(lxev);
+            }
+            else
+            {
+                g_wcstombs(g_clip_c2s.data, wtext, len + 1);
+                g_clip_c2s.total_bytes = g_strlen(g_clip_c2s.data);
+                g_clip_c2s.read_bytes_done = g_clip_c2s.total_bytes;
+                clipboard_provide_selection_c2s(lxev, lxev->target);
+            }
+        }
+        g_free(wtext);
+    }
+    return 0;
+}
+
 /*****************************************************************************/
 /* client to server */
 /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
@@ -1300,75 +1400,46 @@
 clipboard_process_data_response(struct stream *s, int clip_msg_status,
                                 int clip_msg_len)
 {
-    XSelectionRequestEvent *lxev;
-    twchar *wtext;
-    twchar wchr;
-    int len;
-    int index;
+    int rv = 0;
+
+    XSelectionRequestEvent *lxev = &g_saved_selection_req_event;
 
     LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response:");
-    lxev = &g_saved_selection_req_event;
     g_clip_c2s.in_request = 0;
-    if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP)
-    {
-        clipboard_process_data_response_for_image(s, clip_msg_status,
-                clip_msg_len);
-        return 0;
-    }
-    if (g_clip_c2s.xrdp_clip_type == XRDP_CB_FILE)
-    {
-        clipboard_process_data_response_for_file(s, clip_msg_status,
-                clip_msg_len);
-        return 0;
-    }
-    LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response: "
-              "CLIPRDR_DATA_RESPONSE");
-    len = (int)(s->end - s->p);
-    if (len < 1)
+
+    if ((clip_msg_status & CB_RESPONSE_FAIL) != 0)
     {
-        return 0;
+        /* Requested data was not returned from the client. Most likely
+         * the client has lost the selection between announcing it and
+         * responding to our request */
+        clipboard_refuse_selection(lxev);
     }
-    wtext = (twchar *) g_malloc(((len / 2) + 1) * sizeof(twchar), 0);
-    if (wtext == 0)
+    else if ((clip_msg_status & CB_RESPONSE_OK) == 0)
     {
-        return 0;
+        /* One of CB_RESPONSE_FAIL or CB_RESPONSE_OK MUST be set in
+         * a CLIPRDR_FORMAT_DATA_RESPONSE msg */
+        LOG(LOG_LEVEL_ERROR, "CLIPRDR_FORMAT_DATA_RESPONSE is badly formed");
+        clipboard_refuse_selection(lxev);
     }
-    index = 0;
-    while (s_check_rem(s, 2))
+    else if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP)
     {
-        in_uint16_le(s, wchr);
-        wtext[index] = wchr;
-        if (wchr == 0)
-        {
-            break;
-        }
-        index++;
+        clipboard_process_data_response_for_image(s, clip_msg_status,
+                clip_msg_len);
     }
-    wtext[index] = 0;
-    g_free(g_clip_c2s.data);
-    g_clip_c2s.data = 0;
-    g_clip_c2s.total_bytes = 0;
-    len = g_wcstombs(0, wtext, 0);
-    if (len >= 0)
+    else if (g_clip_c2s.xrdp_clip_type == XRDP_CB_FILE)
     {
-        g_clip_c2s.data = (char *) g_malloc(len + 16, 0);
-        if (g_clip_c2s.data == 0)
-        {
-            g_free(wtext);
-            return 0;
-        }
-        g_wcstombs(g_clip_c2s.data, wtext, len + 1);
+        clipboard_process_data_response_for_file(s, clip_msg_status,
+                clip_msg_len);
     }
-    if (g_clip_c2s.data != 0)
+    else
     {
-        g_clip_c2s.total_bytes = g_strlen(g_clip_c2s.data);
-        g_clip_c2s.read_bytes_done = g_clip_c2s.total_bytes;
-        clipboard_provide_selection_c2s(lxev, lxev->target);
+        clipboard_process_data_response_for_text(s, clip_msg_status,
+                clip_msg_len);
     }
-    g_free(wtext);
-    return 0;
+    return rv;
 }
 
+
 /*****************************************************************************/
 static int
 clipboard_process_clip_caps(struct stream *s, int clip_msg_status,
@@ -2295,21 +2366,30 @@
         atom_buf[1] = g_timestamp_atom;
         atom_buf[2] = g_multiple_atom;
         atom_count = 3;
-        if ((g_cfg->restrict_inbound_clipboard & CLIP_RESTRICT_TEXT) == 0)
-        {
-            atom_buf[atom_count] = XA_STRING;
-            atom_count++;
-            atom_buf[atom_count] = g_utf8_atom;
-            atom_count++;
+
+        /* Only announce text if the client is advertising text, or
+         * a file list */
+        if (clipboard_find_format_id(CF_UNICODETEXT) >= 0 ||
+                clipboard_find_format_id(CF_OEMTEXT) >= 0 ||
+                clipboard_find_format_id(CF_TEXT) >= 0 ||
+                clipboard_find_format_id(g_file_group_descriptor_format_id) >= 
0)
+        {
+            if ((g_cfg->restrict_inbound_clipboard & CLIP_RESTRICT_TEXT) == 0)
+            {
+                atom_buf[atom_count] = XA_STRING;
+                atom_count++;
+                atom_buf[atom_count] = g_utf8_atom;
+                atom_count++;
+            }
         }
-        if (clipboard_find_format_id(CB_FORMAT_DIB) >= 0 &&
+        if (clipboard_find_format_id(CF_DIB) >= 0 &&
                 (g_cfg->restrict_inbound_clipboard & CLIP_RESTRICT_IMAGE) == 0)
         {
             LOG_DEVEL(LOG_LEVEL_DEBUG, "  reporting image/bmp");
             atom_buf[atom_count] = g_image_bmp_atom;
             atom_count++;
         }
-        if (clipboard_find_format_id(g_file_format_id) >= 0 &&
+        if (clipboard_find_format_id(g_file_group_descriptor_format_id) >= 0 &&
                 (g_cfg->restrict_inbound_clipboard & CLIP_RESTRICT_FILE) == 0)
         {
             LOG_DEVEL(LOG_LEVEL_DEBUG, "  reporting text/uri-list");
@@ -2353,7 +2433,7 @@
     }
     else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
     {
-        if (clipboard_find_format_id(g_file_format_id) >= 0)
+        if (clipboard_find_format_id(g_file_group_descriptor_format_id) >= 0)
         {
             LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
                       "text requested when files available");
@@ -2371,7 +2451,7 @@
                          sizeof(g_saved_selection_req_event));
                 g_clip_c2s.type = lxev->target;
                 g_clip_c2s.xrdp_clip_type = XRDP_CB_FILE;
-                clipboard_send_data_request(g_file_format_id);
+                clipboard_send_data_request(g_file_group_descriptor_format_id);
             }
 
         }
@@ -2387,11 +2467,14 @@
             }
             else
             {
+                /* The client may have advertised CF_TEXT or CF_OEMTEXT,
+                 * but the Windows clipboard will convert these formats
+                 * to Unicode if asked */
                 g_memcpy(&g_saved_selection_req_event, lxev,
                          sizeof(g_saved_selection_req_event));
                 g_clip_c2s.type = lxev->target;
                 g_clip_c2s.xrdp_clip_type = XRDP_CB_TEXT;
-                clipboard_send_data_request(CB_FORMAT_UNICODETEXT);
+                clipboard_send_data_request(CF_UNICODETEXT);
             }
 
         }
@@ -2430,7 +2513,7 @@
                      sizeof(g_saved_selection_req_event));
             g_clip_c2s.type = g_image_bmp_atom;
             g_clip_c2s.xrdp_clip_type = XRDP_CB_BITMAP;
-            clipboard_send_data_request(CB_FORMAT_DIB);
+            clipboard_send_data_request(CF_DIB);
         }
         return 0;
 
@@ -2467,7 +2550,7 @@
                      sizeof(g_saved_selection_req_event));
             g_clip_c2s.type = g_file_atom1;
             g_clip_c2s.xrdp_clip_type = XRDP_CB_FILE;
-            clipboard_send_data_request(g_file_format_id);
+            clipboard_send_data_request(g_file_group_descriptor_format_id);
             return 0;
         }
 
@@ -2505,7 +2588,7 @@
                      sizeof(g_saved_selection_req_event));
             g_clip_c2s.type = g_file_atom2;
             g_clip_c2s.xrdp_clip_type = XRDP_CB_FILE;
-            clipboard_send_data_request(g_file_format_id);
+            clipboard_send_data_request(g_file_group_descriptor_format_id);
             return 0;
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/sesman/chansrv/clipboard_common.h 
new/xrdp-0.9.23.1/sesman/chansrv/clipboard_common.h
--- old/xrdp-0.9.22.1/sesman/chansrv/clipboard_common.h 2023-05-23 
02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/sesman/chansrv/clipboard_common.h 2023-09-27 
19:59:31.000000000 +0200
@@ -22,19 +22,6 @@
 #include "arch.h"
 #include "parse.h"
 
-/*
- * TODO : Replace these with the definitions in xrdp_constants.h
- * where possible */
-#define CB_FORMAT_RAW                   0x0000
-#define CB_FORMAT_TEXT                  0x0001
-#define CB_FORMAT_DIB                   0x0008
-#define CB_FORMAT_UNICODETEXT           0x000D
-#define CB_FORMAT_HTML                  0xD010
-#define CB_FORMAT_PNG                   0xD011
-#define CB_FORMAT_JPEG                  0xD012
-#define CB_FORMAT_GIF                   0xD013
-#define CB_FORMAT_FILE                  0xC0BC
-
 /* these are the supported general types */
 #define XRDP_CB_TEXT   1
 #define XRDP_CB_BITMAP 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/sesman/session.c 
new/xrdp-0.9.23.1/sesman/session.c
--- old/xrdp-0.9.22.1/sesman/session.c  2023-05-23 02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/sesman/session.c  2023-09-27 19:59:31.000000000 +0200
@@ -526,7 +526,12 @@
         g_delete_wait_obj(g_sigchld_event);
         g_delete_wait_obj(g_term_event);
 
-        auth_start_session(data, display);
+        if (auth_start_session(data, display) != 0)
+        {
+            // Errors are logged by the auth module, as they are
+            // specific to that module
+            g_exit(1);
+        }
         sesman_close_all();
         g_sprintf(geometry, "%dx%d", s->width, s->height);
         g_sprintf(depth, "%d", s->bpp);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/sesman/tools/sesrun.c 
new/xrdp-0.9.23.1/sesman/tools/sesrun.c
--- old/xrdp-0.9.22.1/sesman/tools/sesrun.c     2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/sesman/tools/sesrun.c     2023-09-27 19:59:31.000000000 
+0200
@@ -42,6 +42,11 @@
 
 #include "libscp_connection.h"
 
+// cppcheck doesn't always set this macro to something in double-quotes
+#if defined(__cppcheck__)
+#undef PACKAGE_VERSION
+#endif
+
 #if !defined(PACKAGE_VERSION)
 #define PACKAGE_VERSION "???"
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/sesman/verify_user_pam.c 
new/xrdp-0.9.23.1/sesman/verify_user_pam.c
--- old/xrdp-0.9.22.1/sesman/verify_user_pam.c  2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/sesman/verify_user_pam.c  2023-09-27 19:59:31.000000000 
+0200
@@ -316,8 +316,8 @@
 
 
/******************************************************************************/
 /* returns error */
-int
-auth_start_session(long in_val, int in_display)
+static int
+auth_start_session_private(long in_val, int in_display)
 {
     struct t_auth_info *auth_info;
     int error;
@@ -358,6 +358,26 @@
 }
 
 
/******************************************************************************/
+/**
+ * Main routine to start a session
+ *
+ * Calls the private routine and logs an additional error if the private
+ * routine fails
+ */
+int
+auth_start_session(long in_val, int in_display)
+{
+    int result = auth_start_session_private(in_val, in_display);
+    if (result != 0)
+    {
+        LOG(LOG_LEVEL_ERROR,
+            "Can't start PAM session. See PAM logging for more info");
+    }
+
+    return result;
+}
+
+/******************************************************************************/
 /* returns error */
 int
 auth_stop_session(long in_val)
@@ -419,9 +439,6 @@
     struct t_auth_info *auth_info;
     char **pam_envlist;
     char **pam_env;
-    char item[256];
-    char value[256];
-    int eq_pos;
 
     auth_info = (struct t_auth_info *)in_val;
 
@@ -434,16 +451,16 @@
         {
             for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env)
             {
-                eq_pos = g_pos(*pam_env, "=");
+                char *str = *pam_env;
+                int eq_pos = g_pos(str, "=");
 
-                if (eq_pos >= 0 && eq_pos < 250)
+                if (eq_pos > 0)
                 {
-                    g_strncpy(item, *pam_env, eq_pos);
-                    g_strncpy(value, (*pam_env) + eq_pos + 1, 255);
-                    g_setenv(item, value, 1);
+                    str[eq_pos] = '\0';
+                    g_setenv(str, str + eq_pos + 1, 1);
                 }
 
-                g_free(*pam_env);
+                g_free(str);
             }
 
             g_free(pam_envlist);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/sesman/verify_user_pam_userpass.c 
new/xrdp-0.9.23.1/sesman/verify_user_pam_userpass.c
--- old/xrdp-0.9.22.1/sesman/verify_user_pam_userpass.c 2023-05-23 
02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/sesman/verify_user_pam_userpass.c 2023-09-27 
19:59:31.000000000 +0200
@@ -42,7 +42,7 @@
 auth_userpass(const char *user, const char *pass, int *errorcode)
 {
     pam_handle_t *pamh;
-    pam_userpass_t userpass;
+    pam_userpass_t userpass = NULL;
     struct pam_conv conv = {pam_userpass_conv, &userpass};
     const void *template1;
     int status;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/vrplayer/decoder.h 
new/xrdp-0.9.23.1/vrplayer/decoder.h
--- old/xrdp-0.9.22.1/vrplayer/decoder.h        2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/vrplayer/decoder.h        2023-09-27 19:59:31.000000000 
+0200
@@ -32,7 +32,7 @@
 
     signals:
 
-    public slots:
+    public slots: // cppcheck-suppress unknownMacro
         void onGeometryChanged(QRect *geometry);
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/vrplayer/dlgabout.h 
new/xrdp-0.9.23.1/vrplayer/dlgabout.h
--- old/xrdp-0.9.22.1/vrplayer/dlgabout.h       2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/vrplayer/dlgabout.h       2023-09-27 19:59:31.000000000 
+0200
@@ -19,7 +19,7 @@
     private:
         Ui::DlgAbout *ui;
 
-    private slots:
+    private slots: // cppcheck-suppress unknownMacro
         void onOk();
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/vrplayer/playaudio.h 
new/xrdp-0.9.23.1/vrplayer/playaudio.h
--- old/xrdp-0.9.22.1/vrplayer/playaudio.h      2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/vrplayer/playaudio.h      2023-09-27 19:59:31.000000000 
+0200
@@ -42,7 +42,7 @@
 
         void setVcrOp(int op);
 
-    public slots:
+    public slots: // cppcheck-suppress unknownMacro
         void play();
 
     private:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/vrplayer/playvideo.h 
new/xrdp-0.9.23.1/vrplayer/playvideo.h
--- old/xrdp-0.9.22.1/vrplayer/playvideo.h      2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/vrplayer/playvideo.h      2023-09-27 19:59:31.000000000 
+0200
@@ -46,7 +46,7 @@
         //void setVcrOp(int op);
         //void onMediaRestarted();
 
-    public slots:
+    public slots: // cppcheck-suppress unknownMacro
         void play();
 
         //signals:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/xrdp/xrdp.h 
new/xrdp-0.9.23.1/xrdp/xrdp.h
--- old/xrdp-0.9.22.1/xrdp/xrdp.h       2023-05-23 02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/xrdp/xrdp.h       2023-09-27 19:59:31.000000000 +0200
@@ -345,6 +345,15 @@
 int
 xrdp_font_item_compare(struct xrdp_font_char *font1,
                        struct xrdp_font_char *font2);
+/**
+ * Gets a checked xrdp_font_char from a font
+ * @param f Font
+ * @param c32 Unicode codepoint
+ */
+#define XRDP_FONT_GET_CHAR(f, c32) \
+    (((unsigned int)(c32) >= ' ') && ((unsigned int)(c32) < (f)->char_count) \
+     ? ((f)->chars + (unsigned int)(c32)) \
+     : (f)->default_char)
 
 /* funcs.c */
 int
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/xrdp/xrdp_font.c 
new/xrdp-0.9.23.1/xrdp/xrdp_font.c
--- old/xrdp-0.9.22.1/xrdp/xrdp_font.c  2023-05-23 02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/xrdp/xrdp_font.c  2023-09-27 19:59:31.000000000 +0200
@@ -65,6 +65,12 @@
 };
 #endif
 
+// Unicode definitions
+#define UNICODE_WHITE_SQUARE 0x25a1
+
+// First character allocated in the 'struct xrdp_font.chars' array
+#define FIRST_CHAR ' '
+
 /*****************************************************************************/
 struct xrdp_font *
 xrdp_font_create(struct xrdp_wm *wm)
@@ -74,7 +80,7 @@
     int fd;
     int b;
     int i;
-    int index;
+    unsigned int char_count;
     int datasize;
     int file_size;
     struct xrdp_font_char *f;
@@ -100,17 +106,39 @@
     }
 
     self = (struct xrdp_font *)g_malloc(sizeof(struct xrdp_font), 1);
+    if (self == NULL)
+    {
+        LOG(LOG_LEVEL_ERROR, "xrdp_font_create: "
+            "Can't allocate memory for font");
+        return self;
+    }
     self->wm = wm;
     make_stream(s);
     init_stream(s, file_size + 1024);
     fd = g_file_open(file_path);
 
-    if (fd != -1)
+    if (fd < 0)
+    {
+        LOG(LOG_LEVEL_ERROR,
+            "xrdp_font_create: Can't open %s - %s", file_path,
+            g_get_strerror());
+        g_free(self);
+        self = NULL;
+    }
+    else
     {
         b = g_file_read(fd, s->data, file_size + 1024);
         g_file_close(fd);
 
-        if (b > 0)
+        // Got at least a header?
+        if (b < (4 + 32 + 2 + 2 + 8))
+        {
+            LOG(LOG_LEVEL_ERROR,
+                "xrdp_font_create: Font %s is truncated", file_path);
+            g_free(self);
+            self = NULL;
+        }
+        else
         {
             s->end = s->data + b;
             in_uint8s(s, 4);
@@ -118,11 +146,27 @@
             in_uint16_le(s, self->size);
             in_uint16_le(s, self->style);
             in_uint8s(s, 8);
-            index = 32;
+            char_count = FIRST_CHAR;
 
-            while (s_check_rem(s, 16))
+            while (!s_check_end(s))
             {
-                f = self->font_items + index;
+                if (!s_check_rem(s, 16))
+                {
+                    LOG(LOG_LEVEL_WARNING,
+                        "xrdp_font_create: "
+                        "Can't parse header for character U+%X", char_count);
+                    break;
+                }
+
+                if (char_count >= MAX_FONT_CHARS)
+                {
+                    LOG(LOG_LEVEL_WARNING,
+                        "xrdp_font_create: "
+                        "Ignoring characters >= U+%x", MAX_FONT_CHARS);
+                    break;
+                }
+
+                f = self->chars + char_count;
                 in_sint16_le(s, i);
                 f->width = i;
                 in_sint16_le(s, i);
@@ -139,23 +183,56 @@
                 if (datasize < 0 || datasize > 512)
                 {
                     /* shouldn't happen */
-                    LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create, datasize 
wrong "
-                        "width %d, height %d, datasize %d, index %d",
-                        f->width, f->height, datasize, index);
+                    LOG(LOG_LEVEL_ERROR,
+                        "xrdp_font_create: "
+                        "datasize for U+%x wrong "
+                        "width %d, height %d, datasize %d",
+                        char_count, f->width, f->height, datasize);
                     break;
                 }
 
-                if (s_check_rem(s, datasize))
+                if (!s_check_rem(s, datasize))
                 {
-                    f->data = (char *)g_malloc(datasize, 0);
-                    in_uint8a(s, f->data, datasize);
+                    LOG(LOG_LEVEL_ERROR,
+                        "xrdp_font_create: "
+                        "Not enough data for character U+%X", char_count);
+                    break;
                 }
-                else
+
+                if ((f->data = (char *)g_malloc(datasize, 0)) == NULL)
                 {
-                    LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create");
+                    LOG(LOG_LEVEL_ERROR,
+                        "xrdp_font_create: "
+                        "Allocation error for character U+%X", char_count);
+                    break;
                 }
+                in_uint8a(s, f->data, datasize);
+
+                ++char_count;
+            }
 
-                index++;
+            self->char_count = char_count;
+            if (char_count <= FIRST_CHAR)
+            {
+                /* We read no characters from the font */
+                xrdp_font_delete(self);
+                self = NULL;
+            }
+            else
+            {
+                // Find a default glyph
+                if (char_count > UNICODE_WHITE_SQUARE)
+                {
+                    self->default_char = &self->chars[UNICODE_WHITE_SQUARE];
+                }
+                else if (char_count > '?')
+                {
+                    self->default_char = &self->chars['?'];
+                }
+                else
+                {
+                    self->default_char = &self->chars[FIRST_CHAR];
+                }
             }
         }
     }
@@ -178,16 +255,16 @@
 void
 xrdp_font_delete(struct xrdp_font *self)
 {
-    int i;
+    unsigned int i;
 
     if (self == 0)
     {
         return;
     }
 
-    for (i = 0; i < NUM_FONTS; i++)
+    for (i = FIRST_CHAR; i < self->char_count; i++)
     {
-        g_free(self->font_items[i].data);
+        g_free(self->chars[i].data);
     }
 
     g_free(self);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/xrdp/xrdp_painter.c 
new/xrdp-0.9.23.1/xrdp/xrdp_painter.c
--- old/xrdp-0.9.22.1/xrdp/xrdp_painter.c       2023-05-23 02:18:50.000000000 
+0200
+++ new/xrdp-0.9.23.1/xrdp/xrdp_painter.c       2023-09-27 19:59:31.000000000 
+0200
@@ -455,7 +455,7 @@
 
     for (index = 0; index < len; index++)
     {
-        font_item = self->font->font_items + wstr[index];
+        font_item = XRDP_FONT_GET_CHAR(self->font, wstr[index]);
         rv = rv + font_item->incby;
     }
 
@@ -493,7 +493,7 @@
 
     for (index = 0; index < len; index++)
     {
-        font_item = self->font->font_items + wstr[index];
+        font_item = XRDP_FONT_GET_CHAR(self->font, wstr[index]);
         rv = MAX(rv, font_item->height);
     }
 
@@ -870,7 +870,7 @@
             total_height = 0;
             for (index = 0; index < len; index++)
             {
-                font_item = font->font_items + wstr[index];
+                font_item = XRDP_FONT_GET_CHAR(font, wstr[index]);
                 k = font_item->incby;
                 total_width += k;
                 total_height = MAX(total_height, font_item->height);
@@ -904,7 +904,7 @@
                                      draw_rect.bottom - draw_rect.top);
                     for (index = 0; index < len; index++)
                     {
-                        font_item = font->font_items + wstr[index];
+                        font_item = XRDP_FONT_GET_CHAR(font, wstr[index]);
                         g_memset(&pat, 0, sizeof(pat));
                         pat.format = PT_FORMAT_c1;
                         pat.width = font_item->width;
@@ -946,7 +946,7 @@
 
     for (index = 0; index < len; index++)
     {
-        font_item = font->font_items + wstr[index];
+        font_item = XRDP_FONT_GET_CHAR(font, wstr[index]);
         i = xrdp_cache_add_char(self->wm->cache, font_item);
         f = HIWORD(i);
         c = LOWORD(i);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xrdp-0.9.22.1/xrdp/xrdp_types.h 
new/xrdp-0.9.23.1/xrdp/xrdp_types.h
--- old/xrdp-0.9.22.1/xrdp/xrdp_types.h 2023-05-23 02:18:50.000000000 +0200
+++ new/xrdp-0.9.23.1/xrdp/xrdp_types.h 2023-09-27 19:59:31.000000000 +0200
@@ -574,7 +574,7 @@
     int crc16;
 };
 
-#define NUM_FONTS 0x4e00
+#define MAX_FONT_CHARS 0x4e00
 #define DEFAULT_FONT_NAME "sans-10.fv1"
 
 #define DEFAULT_ELEMENT_TOP   35
@@ -594,7 +594,11 @@
 struct xrdp_font
 {
     struct xrdp_wm *wm;
-    struct xrdp_font_char font_items[NUM_FONTS];
+    // Font characters, accessed by Unicode codepoint. The first 32
+    // entries are unused.
+    struct xrdp_font_char chars[MAX_FONT_CHARS];
+    unsigned int char_count; // # elements in above array
+    struct xrdp_font_char *default_char; // Pointer into above array
     char name[32];
     int size;
     int style;

Reply via email to