[newlib-cygwin/cygwin-3_6-branch] Cygwin: console: Fix handling of surrogate pairs

Takashi Yano via Cygwin-cvs <[email protected]> Fri, 29 May 2026 02:34:01 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D231c2b90b84=
8aec4db9718c4c5b4747d2f186e25

commit 231c2b90b848aec4db9718c4c5b4747d2f186e25
Author: Takashi Yano <[email protected]>
Date:   Tue May 26 18:40:30 2026 +0900

    Cygwin: console: Fix handling of surrogate pairs
   =20
    The commit 782aac590af7 introduced surrogate-pair handling. However,
    it does not work as expected in the legacy console. This is because,
    in legacy console, a KeyDown event for ALT key with UnicodeChar =3D=3D 0
    is inserted between the surrogate pair. The current code reads the
    next input event unconditionally for the second UnicodeChar, but it
    is not correct. This patch searches the next appropriate key event
    with a valid UnicodeChar, ensuring that the second code unit is valid.
   =20
    Fixes: 782aac590af7 ("Cygwin: console: Handle Unicode surrogate pairs.")
    Signed-off-by: Takashi Yano <[email protected]>
    Reviewed-by: Johannes Schindelin <[email protected]>
    (cherry picked from commit 1ff8990c0b8918c9ecad96314efa3f580a5e575c)

Diff:
---
 winsup/cygwin/fhandler/console.cc | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/con=
sole.cc
index 224177bd5..ca32d7faa 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -1399,9 +1399,21 @@ fhandler_console::process_input_message (void)
 	    }
 	  else
 	    {
-	      WCHAR second =3D unicode_char >=3D 0xd800 && unicode_char <=3D 0xdb=
ff
-		  && i + 1 < total_read ?
-		  input_rec[i + 1].Event.KeyEvent.uChar.UnicodeChar : 0;
+	      WCHAR second =3D 0;
+	      DWORD second_pos =3D i;
+	      if (unicode_char >=3D 0xd800 && unicode_char <=3D 0xdbff)
+		for (DWORD j =3D i + 1; j < total_read; j++)
+		  {
+		    /* Do not check bKeyDown. bKeyDown is 0 for surrogate
+		       pair in legacy console */
+		    if (input_rec[j].EventType =3D=3D KEY_EVENT &&
+			input_rec[j].Event.KeyEvent.uChar.UnicodeChar)
+		      {
+			second =3D input_rec[j].Event.KeyEvent.uChar.UnicodeChar;
+			second_pos =3D j;
+			break;
+		      }
+		  }
=20
 	      if (second < 0xdc00 || second > 0xdfff)
 		{
@@ -1412,7 +1424,7 @@ fhandler_console::process_input_message (void)
 		  /* handle surrogate pairs */
 		  WCHAR pair[2] =3D { unicode_char, second };
 		  nread =3D sys_wcstombs (tmp + 1, 59, pair, 2);
-		  i++;
+		  i =3D second_pos;
 		}
=20
 	      /* Determine if the keystroke is modified by META.  The tricky