On Friday 19 December 2025 14:36:04 Martin Storsjö wrote:
> On Fri, 19 Dec 2025, Pali Rohár wrote:
>
> > On Friday 19 December 2025 14:02:43 Martin Storsjö wrote:
> > > On Fri, 19 Dec 2025, Pali Rohár wrote:
> > >
> > > > On Tuesday 18 November 2025 16:46:43 Pali Rohár wrote:
> > > > > On Monday 17 November 2025 22:06:40 Martin Storsjö wrote:
> > > > > > On Mon, 17 Nov 2025, Pali Rohár wrote:
> > > > > >
> > > > > > > On Monday 17 November 2025 17:13:56 Martin Storsjö wrote:
> > > > > > > > On Sat, 25 Oct 2025, Pali Rohár wrote:
> > > > > > > >
> > > > > > > > > Format %Z takes pointer to ANSI_STRING or UNICODE_STRING
> > > > > > > > > based on the
> > > > > > > > > wideness of format.
> > > > > > > > >
> > > > > > > > > In this mingw-w64 implementation (same as in UCRT) the
> > > > > > > > > uppercase format %Z
> > > > > > > > > has the same default wideness as uppercase format %S when no
> > > > > > > > > h, l or w
> > > > > > > > > modifier is specified.
> > > > > > > > >
> > > > > > > > > Format %Z is supported by crtdll, msvcrt and UCRT libraries.
> > > > > > > > > There are some
> > > > > > > > > differences between individual CRT versions regarding the
> > > > > > > > > wide wprintf(%lZ),
> > > > > > > > > narrow printf(%Z/%lZ) and whether nul chars in ANSI_STRING
> > > > > > > > > are accepted by
> > > > > > > > > wprintf or not. In mingw-w64 for compatibility reasons are
> > > > > > > > > accepted.
> > > > > > > >
> > > > > > > > The last sentence, "In mingw-w64 for compatibility reasons are
> > > > > > > > accepted."
> > > > > > > > seems like it is missing something, in order to make sense.
> > > > > > >
> > > > > > > Ah, right, there is missing "they" (nul chars). Should be "they
> > > > > > > are accepted".
> > > > > > >
> > > > > > > > > diff --git a/mingw-w64-crt/stdio/mingw_pformat.c
> > > > > > > > > b/mingw-w64-crt/stdio/mingw_pformat.c
> > > > > > > > > index bdc7eba2a573..ded916c9a2bc 100644
> > > > > > > > > --- a/mingw-w64-crt/stdio/mingw_pformat.c
> > > > > > > > > +++ b/mingw-w64-crt/stdio/mingw_pformat.c
> > > > > > > > > @@ -66,6 +66,7 @@
> > > > > > > > > #include <limits.h>
> > > > > > > > > #include <locale.h>
> > > > > > > > > #include <wchar.h>
> > > > > > > > > +#include <ntdef.h>
> > > > > > > > >
> > > > > > > > > #ifdef __ENABLE_DFP
> > > > > > > > > #ifndef __STDC_WANT_DEC_FP__
> > > > > > > > > @@ -2558,6 +2559,64 @@ __pformat (int flags, void *dest, int
> > > > > > > > > max, const APICHAR *fmt, va_list argv)
> > > > > > > > > */
> > > > > > > > > __pformat_puts( va_arg( argv, char * ), &stream
> > > > > > > > > );
> > > > > > > > > goto format_scan;
> > > > > > > > > +
> > > > > > > > > + case 'Z':
> > > > > > > > > + /*
> > > > > > > > > + * The logic for `%Z` length modifier is quite
> > > > > > > > > complicated.
> > > > > > > > > + *
> > > > > > > > > + * for printf:
> > > > > > > > > + * `%Z` - UNICODE_STRING for UCRT; ANSI_STRING
> > > > > > > > > for crtdll,msvcrt10,msvcrt,msvcr80-msvcr120
> > > > > > > > > + * `%hZ` - ANSI_STRING
> > > > > > > > > + * `%lZ` - UNICODE_STRING for UCRT; ANSI_STRING
> > > > > > > > > for crtdll,msvcrt10,msvcrt,msvcr80-msvcr120
> > > > > > > > > + * `%wZ` - UNICODE_STRING
> > > > > > > > > + *
> > > > > > > > > + * for wprintf:
> > > > > > > > > + * `%Z` - ANSI_STRING
> > > > > > > > > + * `%hZ` - ANSI_STRING
> > > > > > > > > + * `%lZ` - UNICODE_STRING for UCRT; ANSI_STRING
> > > > > > > > > for crtdll,msvcrt10,msvcrt,msvcr80-msvcr120
> > > > > > > > > + * `%wZ` - UNICODE_STRING
> > > > > > > > > + *
> > > > > > > > > + * There are some other changes between versions
> > > > > > > > > regarding nul chars.
> > > > > > > > > + * - msvcrt since Vista, msvcr80+ and UCRT do
> > > > > > > > > not accept nul chars in ANSI_STRING for wprintf. They stop at
> > > > > > > > > nul char and returns -1.
> > > > > > > > > + * - crtdll, msvcrt10 and msvcrt before Vista
> > > > > > > > > accept nul char in ANSI_STRING for wprintf, but ANSI_STRING
> > > > > > > > > content after nul char is discarded.
> > > > > > > >
> > > > > > > > This explanation doesn't feel like it makes sense to me. If it
> > > > > > > > accepts the
> > > > > > > > nul char, the wouldn't it also proceed after that? So do you
> > > > > > > > say that it
> > > > > > > > includes the single nul char in the output, but nothing after
> > > > > > > > it? While the
> > > > > > > > logical thing would be to either stop at the nul (not
> > > > > > > > outputting it) or
> > > > > > > > include everything?
> > > > > > >
> > > > > > > I used term "accept" whether wprintf will continue or immediately
> > > > > > > returns -1. I think that this was the main confusing here.
> > > > > >
> > > > > > No, the main confusion here is that some of the sentences here are
> > > > > > contradicting themselves. The core of the confusion is above:
> > > > > >
> > > > > > "crtdll, msvcrt10 and msvcrt before Vista accept nul char in
> > > > > > ANSI_STRING for
> > > > > > wprintf, but ANSI_STRING content after nul char is discarded."
> > > > > >
> > > > > > Here you describe two different behaviours for ANSI_STRING. Do you
> > > > > > mean one
> > > > > > behaviour for ANSI_STRING and one for UNICODE_STRING?
> > > > > >
> > > > > > // Martin
> > > > >
> > > > > Ok, I will to rephrase that sentence:
> > > > >
> > > > > crtdll, msvcrt10 and msvcrt before Vista accept ANSI_STRING with nul
> > > > > chars in wprintf call, but the first nul char and everything after it
> > > > > in
> > > > > the ANSI_STRING content is ignored and not printed by wprintf at all.
> > > >
> > > > It is more clear my above last comment about behavior?
> > >
> > > No it is still unclear.
> > >
> > > Going back to the original quoted comment above:
> > >
> > > + * - msvcrt since Vista, msvcr80+ and UCRT do not accept nul
> > > chars in ANSI_STRING for wprintf. They stop at nul char and returns -1.
> > > + * - crtdll, msvcrt10 and msvcrt before Vista accept nul char
> > > in ANSI_STRING for wprintf, but ANSI_STRING content after nul char is
> > > discarded.
> > >
> > > Do you mean this:
> > >
> > > - In both modes, printing stops at nul char in ANSI_STRING
> >
> > In old versions, when the nul char is detected, char is not printed
> > and wprintf function jumps and continue formatting the next %format
> > argument. So it skips the nul char and everything after the nul char in
> > the current ANSI_STRING %format argument. But all remaining %format
> > arguments are processed.
> >
> > In new version, when the nul char is detected, char is not printed and
> > wprintf function returns -1. So it skips the nul char and everything
> > after nul char in the current ANSI_STRING %format argument. And it also
> > skips also all other remaining %format arguments.
> >
> > Lets take this example:
> >
> > wprintf(L"%d%hZ%d", 1, compose_ANSI_STRING("A\0B"), 2);
> >
> > Old version returns <success> and prints: "1A2"
> > New version returns <failure> (-1) and prints: "1A"
>
> Ok, I see - this makes it clear.
>
> To clarify your original comment:
>
> + * - msvcrt since Vista, msvcr80+ and UCRT do not accept nul
> chars in ANSI_STRING for wprintf. They stop at nul char and returns -1.
> + * - crtdll, msvcrt10 and msvcrt before Vista accept nul char
> in ANSI_STRING for wprintf, but ANSI_STRING content after nul char is
> discarded.
>
> Admittedly, after your explanation above, this comment does read
> understandably. But that doesn't help for people reading it the first
> time...
>
> Maybe it would be clearer like this:
>
> * - msvcrt since Vista, msvcr80+ and UCRT do not accept nul chars in
> ANSI_STRING for wprintf. If encountering a nul char, it stops processing the
> format string and returns -1.
> * - crtdll, msvcrt10 and msvcrt before Vista accept nul char in ANSI_STRING
> for wprintf, but ANSI_STRING content after nul char is discarded.
>
> // Martin
Ok. Thank you. What about following text? To make it clear if the nul
char itself is ignored or printed.
Because this (narrow printf):
printf("%d%hZ%d", 1, compose_ANSI_STRING("A\0B"), 2);
returns <success> and prints: "1A\0B2"
* There are some other changes between versions regarding nul chars.
* - msvcrt since Vista, msvcr80+ and UCRT do not accept nul chars in
ANSI_STRING for wprintf.
* If encountering a nul char, it stops processing the format string and
returns -1.
* - crtdll, msvcrt10 and msvcrt before Vista accept nul char in ANSI_STRING for
wprintf,
* but the first nul char and everything after it in ANSI_STRING content is
discarded.
* - ANSI_STRING for printf, and UNICODE_STRING for both printf and wprintf
works fine
* in all versions, every nul byte in the string is processed and printed.
*
* This mingw-w64 implementation uses UCRT behavior of length modifiers.
* And for compatibility with older msvcrt versions, wprintf discards
* nul char and content after it in ANSI_STRING, and continue processing
* of the format string (like msvcrt before Vista).
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public