On Wednesday 25 February 2026 19:16:27 Lasse Collin wrote:
> On 2026-02-24 Pali Rohár wrote:
> > Hello, in attachment I'm sending a change which fixes mingw-w64 POSIX
> > non-underscored stat() and wstat() function(s) (including large file
> > and 64-bit time variants) for msvcrt.dll builds when calling stat on
> > various Win32 device files (like "NUL") or when using "\\?\\\\"
> > prefix. The MS underscored _stat / _wstat functions are untouched and
> > stay as it.
> 
> I didn't test anything, but by reading the code:
> 
> The first commit looks good. It reduces code duplication.

Thanks.

> In the second patch, if __MINGW_FIX_STAT_PATH returns NULL when
> filename != NULL, it means that malloc failed, and the contents of
> struct stat (or whatever the exact type of *obj is) are undefined. It
> would be good to just return the error instead of calling
> __MINGW_FIX_STAT_FALLBACK_FD. That is, move the
> __MINGW_FIX_STAT_FALLBACK_FD inside the else-block:
> 
> #define __MINGW_FIXED_STAT(fstat_func, stat_func, filename, obj) ({ \
>   /* First call CRT _stat function with mingw path correction */ \
>   int _stat_ret; \
>   __MINGW_PATH_PTR_TYPE(filename) path = __MINGW_FIX_STAT_PATH(filename); \
>   if (path == NULL && (filename) != NULL) { \
>     _stat_ret = -1; \
>   } else { \
>     _stat_ret = (stat_func)(path, (obj)); \
>     _stat_ret = __mingw_fix_stat_finish(_stat_ret, (filename), path, 
> (obj)->st_mode); \
>     /* If the CRT _stat function failed then fallback to mingw fstat function 
> */ \
>     int _stat_fd = __MINGW_FIX_STAT_FALLBACK_FD(_stat_ret, (filename), 
> (obj)->st_mode); \
>     if (_stat_fd >= 0) { \
>       _stat_ret = fstat_func(_stat_fd, (void*)(obj)); \
>       int _stat_errno = errno; \
>       close(_stat_fd); \
>       errno = _stat_errno; \
>     } \
>   } \
>   _stat_ret; \
> })
> 
> Without this change, the "mode" in S_ISREG(mode) in
> __mingw_fix_stat_fallback_fd.c will have an undefined value after
> __MINGW_FIX_STAT_PATH failure.

That is really an issue. On failure the stat buffer is untouched. I will
move that code block as you suggested.

> Even with this change, S_ISREG(mode) can be executed after stat_func
> has failed. I suspect that the stat_funcs don't necessarily initialize
> *obj on failure. Thus, the condition in __mingw_fix_stat_fallback_fd.c
> should check ret before S_ISREG(mode):
> 
>     if ((ret < 0 && errno == ENOENT && __MINGW_STR_PBRK((filename), "?*")) || 
> (ret == 0 && S_ISREG(mode))) {

This is also an issue, I forgot about that ret == 0 part. I will add it.

> * * *
> 
> In __mingw_fix_stat_fallback_fd.c, this comment is confusing:
> 
>     CRT _stat does not handle paths with wildcard ? and * and returns ENOENT.
> 
> Assuming it's about \\?\ paths, a few extra words would help:
> 
>     CRT _stat does not handle paths with ? and * characters and returns
>     ENOENT. This prevents _stat from working on paths like
>     \\?\C:\foo.txt.

Ok, I will include this description. That makes sense.

> In a comment a few lines later, there is a typo. "id" should be "fd":
> 
>     ...and return id if CRT _stat failed...

I spotted this type after I send an email.

I will send new version of this change with all those fixes later.

> > Note that UCRT build does not have these issues and it is verified by
> > automated test, part of change. So this change does not touch UCRT
> > builds.
> 
> Since UCRT isn't new anymore, hopefully these MSVCRT issues can soon be
> declared as features, and people can be told to use UCRT when the
> MSVCRT oddities are a problem.
> 
> -- 
> Lasse Collin

Or better, people can be told to not use underscored _*stat* functions.


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

Reply via email to