Re: [PATCH] Cygwin: console: Fix handling of surrogate pairs

Johannes Schindelin <[email protected]> Thu, 28 May 2026 15:33:24 +0200 (CEST)
Newsgroups gmane.os.cygwin.patches
Message-ID <[email protected]>
Hi Takashi,

On Tue, 26 May 2026, Takashi Yano wrote:

> The commit 782aac590af7 introduced surrogate-pair handling. However,
> it does not work as expected in the legacy console. This is because
> a KeyDown event for ALT key with UnicodeChar == 0 is inserted the
> between surrogate pair. The current code reads the next key 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.
> 
> Fixes: 782aac590af7 ("Cygwin: console: Handle Unicode surrogate pairs.")
> Signed-off-by: Takashi Yano <[email protected]>
> Reviewed-by:
> ---
>  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/console.cc
> index 6fd4cd965..45eff6efe 100644
> --- a/winsup/cygwin/fhandler/console.cc
> +++ b/winsup/cygwin/fhandler/console.cc
> @@ -1452,9 +1452,21 @@ fhandler_console::process_input_message (void)
>  	    }
>  	  else
>  	    {
> -	      WCHAR second = unicode_char >= 0xd800 && unicode_char <= 0xdbff
> -		  && i + 1 < total_read ?
> -		  input_rec[i + 1].Event.KeyEvent.uChar.UnicodeChar : 0;
> +	      WCHAR second = 0;
> +	      DWORD second_pos = i;
> +	      if (unicode_char >= 0xd800 && unicode_char <= 0xdbff)
> +		for (DWORD j = i + 1; j < total_read; j++)
> +		  {
> +		    /* Do not check bKeyDown. bKeyDown is 0 for surrogate
> +		       pair in legacy console */
> +		    if (input_rec[j].EventType == KEY_EVENT &&
> +			input_rec[j].Event.KeyEvent.uChar.UnicodeChar)
> +		      {
> +			second = input_rec[j].Event.KeyEvent.uChar.UnicodeChar;
> +			second_pos = j;
> +			break;
> +		      }
> +		  }
>  
>  	      if (second < 0xdc00 || second > 0xdfff)
>  		{
> @@ -1465,7 +1477,7 @@ fhandler_console::process_input_message (void)

It's a bit unfortunate that the diff here hides the fact that the
following is in the `else` branch...

In any case, the patch makes sense to me, and I really appreciate the
commit message that puts the diff into context.

Thanks!
Johannes

>  		  /* handle surrogate pairs */
>  		  WCHAR pair[2] = { unicode_char, second };
>  		  nread = sys_wcstombs (tmp + 1, 59, pair, 2);
> -		  i++;
> +		  i = second_pos;
>  		}
>  
>  	      /* Determine if the keystroke is modified by META.  The tricky
> -- 
> 2.51.0
> 
>