[PATCH] mbrtowc: Avoid compare with the result pointer add

YunQiang Su yunqiang@isrc.iscas.ac.cn
Fri Jan 10 03:12:54 GMT 2025



> 2025年1月10日 11:00,YunQiang Su <yunqiang@isrc.iscas.ac.cn> 写道:
> 
>  inbuf = (const unsigned char *) s;
>  endbuf = inbuf + n;
>  if (__glibc_unlikely (endbuf < inbuf))  // <--- here
>    {
>      endbuf = (const unsigned char *) ~(uintptr_t) 0;
>      if (endbuf == inbuf)
>        goto ilseq;
>    }
> 
> Some compilers (such as clang 20), may treat that the endbuf
> greater than inbuf always, as n is a `size_t`, aka `unsigned long`.
> 
> Let's use
>   if (__glibc_unlikely ((ssize_t)n < 0))
> instead.
> ---
> wcsmbs/mbrtowc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/wcsmbs/mbrtowc.c b/wcsmbs/mbrtowc.c
> index 47068ed0e0..124f4b6f0a 100644
> --- a/wcsmbs/mbrtowc.c
> +++ b/wcsmbs/mbrtowc.c
> @@ -71,7 +71,7 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
>   /* Do a normal conversion.  */
>   inbuf = (const unsigned char *) s;
>   endbuf = inbuf + n;
> -  if (__glibc_unlikely (endbuf < inbuf))
> +  if (__glibc_unlikely ((ssize_t)n < 0))

This patch is incorrect, Sorry for the noisy.
For example on a 32bit system:
If `inbuf` is 8, and `n` is 0x80000008
    `endbuf < inbuf` is false
while
    (ssize_t)n < 0    is true.

>     {
>       endbuf = (const unsigned char *) ~(uintptr_t) 0;
>       if (endbuf == inbuf)
> -- 
> 2.39.5 (Apple Git-154)



More information about the Libc-alpha mailing list