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, the return code of wprintf indicate success, in new versions the return code indicate failure (but has already output the earlier chars before this)?

If not, what do you mean by "They stop at nul char"? Do you mean that if the ANSI_STRING contains a nul char anywhere, the function returns an error before outputting anything?

// Martin

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to