On Tue, 12 Nov 2024, Pali Rohár wrote:

- The commit message explanation of _swprintf_c seems weird. The commit
message says:

      _(v)swprintf_c - clears the first wide character in buffer on error
                       (error means that there is no space for nul-term or
                       conversion error occurred)

However I don't see that behaviour (clearing the _first_ char in the buffer
on error sounds odd - then the whole buffer would be an empty string?). Can
you recheck this explanation? In any case, this function seemed fringe
enough that I didn't add a test for it.

Ok. I will recheck it. IIRC I tried to decode header files, and I'm not
sure if I still have test case for this function, as this function
something not very widely used.

Indeed, it seems very rare.

Yes, it is rare and I have included it into commit message just because
of completeness and to explain why cannot use it as alias for the
compliant swprintf.

Ah, I see.

Maybe we should rather test that swprintf returns negative value in this
case and skip this test case for MSVC?

I think I'll just skip this test altogether, as we get the wrong result with
UCRT in mingw as well, and with msvcrt when not using
__USE_MINGW_ANSI_STDIO.

That is bad if we are getting wrong/different results.

I looked at it and it is a real bug which you found. It is in the file:
mingw-w64-crt/stdio/vswprintf.c

int __cdecl __ms_vswprintf(wchar_t *__restrict__ ws, size_t n, const wchar_t 
*__restrict__ format, va_list arg)
{
   int retval;

   retval = _vsnwprintf(ws, n-1, format, arg);

When n=0 then _vsnwprintf is called with MAX_SIZE_T value.

Now I checked that _vsnwprintf() in msvcr* returns -1 when n=0.

Oh, good catch!

I'm going to apply following change to fix n-1 underflow:

diff --git a/mingw-w64-crt/stdio/vswprintf.c b/mingw-w64-crt/stdio/vswprintf.c
index f7bdc3cdc897..7edc52050711 100644
--- a/mingw-w64-crt/stdio/vswprintf.c
+++ b/mingw-w64-crt/stdio/vswprintf.c
@@ -11,6 +11,9 @@ int __cdecl __ms_vswprintf(wchar_t *__restrict__ ws, size_t 
n, const wchar_t *__
{
    int retval;

+    if (n == 0)
+        return -1;
+
    retval = _vsnwprintf(ws, n-1, format, arg);

    /* _vsnwprintf() does not fill trailing nul wide char if there is not place 
for it */

It is fine?

That seems good to me.

I think that the test for this n=0 case is really useful as it already
found a bug in my new code.

Ok, sure - if we'd get consistent behaviour across msvcrt/__USE_MINGW_ANSI_STDIO/ucrt, I can readd that check. But I guess that fix only affects msvcrt - it won't fix it for UCRT, or will it? I wonder if it's worth the effort to wrap the UCRT function "just" for this.

// Martin

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to