On Sunday 21 June 2026 06:25:22 Kirill Makurin wrote:
> Pali Rohár <[email protected]> wrote:
> 
> > For the "[PATCH 3/3] crt: improve _wassert() emulation" I would propose
> > small improvement (changes attached). It implements decision based on
> > _set_error_mode() (as it was already written in the comment)
> 
> Can we do this as a follow-up? As I mentioned in previous email, I like the 
> idea and wanted to suggest it.

Sure. That is why I sent it a separate change.

> > use alloca
> > instead of _alloca (alloca is GNU name and mingw-w64 crt already uses
> > the non-underscore variant) and reduce calculation of alloca buffers.
> 
> I think we should keep using MS function names internally.

I think that this makes sense for MS functions from DLL library. But
here the alloca is the gcc/clang function, because such thing is
provided by the compiler, not by the runtime library.

> > Currently it first tries to estimate buffer size based on wcsnlen and
> > MB_LEN_MAX. Then it calculates the real buffer size correctly via
> > WideCharToMultiByte() and third time it is using WideCharToMultiByte()
> > for the final conversion. So the first step via wcsnlen and MB_LEN_MAX
> > is not needed, the real size can be calculated directly.
> 
> I think you misunderstood the purpose of `wcsnlen` trick.
> 
> So, basically, we limit `_alloca` allocation size to `BUFSIZ` for `_Message` 
> arg and to `FILENAME_MAX` for `_File` arg. The `wcsnlen` trick is used to 
> allocate smaller buffer when we can ensure that length of converted string 
> will never exceed `BUFSIZ` or `FILENAME_MAX`. It is an attempt to reduce 
> possibility of stack overflow. While doing so, I overlooked a stupid 
> off-by-one error...

I understood it. The first call to WideCharToMultiByte() just calculate
the total length of buffer required to do full conversion. It is doing
without any side-effect and without writing anything to do buffer.
So we can use lenght := min(output_from_WideCharToMultiByte, BUFSIZ) and
then use this length for passing to alloca (with +1 or something like
that). And with this we allocate smaller buffer when not full BUFSIZ is
needed and also at the same time we do not need to call wcsnlen and do
some estimation.

> > Also memset is not needed.
> 
> I'm pretty sure it is needed. `WideCharToMultiByte` writes NUL to output 
> buffer only if it was converted.
> 
> Consider string "テクスト" whose length is 12 code units (+NUL) in UTF-8 or 8 
> code units (+NUL) in code page 932. Now, if you call
> 
>     WideCharToMultiByte (CP_UTF8, 0, L"テクスト", -1, buf, 10, NULL, NULL)
> 
> It will write "テクス" to `buf` and not NUL-terminate it. Call to `memset` 
> ensures that string will always be NUL-terminated.
> 
> - Kirill Makurin

I see. In my proposed change I always put the explicit nul term after
the WideCharToMultiByte() call at the end of conversion, to be sure that
it is always nul term. So only with this change it is not needed.


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

Reply via email to