On Sun, 13 Apr 2025, Pali Rohár wrote:

For POSIX stat compatibility, it is not possible to use msvcrt _stat32() or
_stat64i32() from crtdll.dll - msvcr100.dll CRT libraries as their
implementations do not signal EOVERFLOW error when file size does not fit
into the stat's st_size field. Signalling EOVERFLOW is required for POSIX
compatibility. New CRT libraries (msvcr110.dll, msvcr120.dll and UCRT) have
implementation of _stat32() and _stat64i32() more compatible with POSIX and
properly return EOVERFLOW when file size does not fit into the struct
stat's st_size field.

So for pre-msvcr110 builds, use only _stat64() function for implementing
POSIX stat in mingw-w64 and do check overflow in mingw-w64 the wrapper.
---
mingw-w64-crt/Makefile.am                     | 39 +++++++++++++++----
.../stdio/{stat32.c => msvcr110plus_stat32.c} |  0
.../{stat64i32.c => msvcr110plus_stat64i32.c} |  0
.../{wstat32.c => msvcr110plus_wstat32.c}     |  0
...wstat64i32.c => msvcr110plus_wstat64i32.c} |  0
.../stdio/{stat32.c => msvcr110pre_stat32.c}  | 28 ++++++++++++-
.../{stat64i32.c => msvcr110pre_stat64i32.c}  | 28 ++++++++++++-
.../{wstat32.c => msvcr110pre_wstat32.c}      | 28 ++++++++++++-
...{wstat64i32.c => msvcr110pre_wstat64i32.c} | 28 ++++++++++++-
9 files changed, 136 insertions(+), 15 deletions(-)
copy mingw-w64-crt/stdio/{stat32.c => msvcr110plus_stat32.c} (100%)
copy mingw-w64-crt/stdio/{stat64i32.c => msvcr110plus_stat64i32.c} (100%)
copy mingw-w64-crt/stdio/{wstat32.c => msvcr110plus_wstat32.c} (100%)
copy mingw-w64-crt/stdio/{wstat64i32.c => msvcr110plus_wstat64i32.c} (100%)
rename mingw-w64-crt/stdio/{stat32.c => msvcr110pre_stat32.c} (56%)
rename mingw-w64-crt/stdio/{stat64i32.c => msvcr110pre_stat64i32.c} (57%)
rename mingw-w64-crt/stdio/{wstat32.c => msvcr110pre_wstat32.c} (57%)
rename mingw-w64-crt/stdio/{wstat64i32.c => msvcr110pre_wstat64i32.c} (58%)

index 9623c80f5b35..4d5d33c61344 100644
--- a/mingw-w64-crt/stdio/stat32.c
+++ b/mingw-w64-crt/stdio/msvcr110pre_stat32.c
@@ -6,17 +6,41 @@

#include <sys/stat.h>
#include <stdlib.h>
+#include <stdint.h>

char *__mingw_fix_stat_path(const char *_path);

+/* For pre-msvcr110 builds, we cannot use _stat32() function as it does
+ * not signal EOVERFLOW when file size does not fit into the st_size field,
+ * as it is required by POSIX stat() function.
+ * This file is used only for pre-msvcr110 builds.
+ */
int __cdecl stat32(const char *_Filename, struct _stat32 *_Stat);
int __cdecl stat32(const char *_Filename, struct _stat32 *_Stat)
{
+  struct _stat32i64 st;
  char *_path = __mingw_fix_stat_path(_Filename);
-  int ret = _stat32(_path, _Stat);
+  int ret = _stat32i64(_path, &st);
  if (_path != _Filename)
    free(_path);
-  return ret;
+  if (ret != 0)
+    return ret;
+  if (st.st_size > UINT32_MAX) {
+    errno = EOVERFLOW;
+    return -1;
+  }

This, and a couple other cases in this file, are missing includes of errno.h. With GCC, this header seems to end up included transitively somehow, but with Clang it isn't.

I've fixed this locally in my branch though.

// Martin

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

Reply via email to