[PATCH] wcstombs: also call __WCTOMB on terminating NUL if output buffer is NULL

Christian Franke Christian.Franke@t-online.de
Tue Jul 1 09:17:07 GMT 2025


Testcase (requires sizeof(wchar_t)==2):

$ uname -sr
CYGWIN_NT-10.0-22631 3.7.0-0.165.g1b60f4861b70.x86_64

$ cat mbslen.c
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>

int main()
{
   setlocale(LC_ALL, "en_US.UTF-8");
   const wchar_t w[] = L"t-\xD801";
   size_t n1 = wcstombs(NULL, w, 0);
   char s[42]; // "t-\xED\xA0\x81"
   size_t n2 = wcstombs(s, w, sizeof(s));
   printf("n1=%zd\nn2=%zd\n", n1, n2);
   return 0;
}

$ gcc -W -Wall -o mbslen mbslen.c

$ ./mbslen
n1=2
n2=5

-- 
Regards,
Christian

-------------- next part --------------
From 32a58b0df028c5894f4a8d02fabf89a8d90e16f2 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.franke@t-online.de>
Date: Tue, 1 Jul 2025 11:00:41 +0200
Subject: [PATCH] wcstombs: also call __WCTOMB on terminating NUL if output
 buffer is NULL

A __WCTOMB call on the terminating NUL may emit more than a NUL byte.
This is the case if the string ends with a lone UTF-16 high surrogate.

Fixes: 2a3a02a68764 ("Add SUSV2 support for calculating size if output buffer is NULL")
Signed-off-by: Christian Franke <christian.franke@t-online.de>
---
 newlib/libc/stdlib/wcstombs_r.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/newlib/libc/stdlib/wcstombs_r.c b/newlib/libc/stdlib/wcstombs_r.c
index c6a06a39a..2c82a2c25 100644
--- a/newlib/libc/stdlib/wcstombs_r.c
+++ b/newlib/libc/stdlib/wcstombs_r.c
@@ -17,14 +17,15 @@ _wcstombs_r (struct _reent *r,
   if (s == NULL)
     {
       size_t num_bytes = 0;
-      while (*pwcs != 0)
+      do
 	{
-	  bytes = __WCTOMB (r, buff, *pwcs++, state);
+	  bytes = __WCTOMB (r, buff, *pwcs, state);
 	  if (bytes == -1)
 	    return -1;
 	  num_bytes += bytes;
 	}
-      return num_bytes;
+      while (*pwcs++ != 0x00);
+      return num_bytes - 1;
     }
   else
     {
-- 
2.45.1



More information about the Newlib mailing list