Skip to content

Commit

Permalink
os_compat: use correct struct stat in Windows
Browse files Browse the repository at this point in the history
The stat macro in os_compat.h shadowed the stat macro in mingw64
headers, which caused proceeding code to use a stat structure with
32-bit st_size instead of the 64-bit struct _stat64 used by win32_stat
and _wstat64. Those structs have a different size, which was causing
win32_stat to corrupt adjacent variables on the stack.

Since using macros for stat is tricky, avoid macros by defining
crip_stat instead.
  • Loading branch information
rossy authored and cyanreg committed Jun 10, 2023
1 parent c099d42 commit cee41bd
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/cyanrip_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ char *crip_get_path(cyanrip_ctx *ctx, enum CRIPPathType type, int create_dirs,
for (int i = 0; i < dir_list_nb; i++) {
if (create_dirs) {
struct stat st_req = { 0 };
if (stat(dir_list[i], &st_req) == -1)
if (crip_stat(dir_list[i], &st_req) == -1)
mkdir(dir_list[i], 0700);
}
av_free(dir_list[i]);
Expand Down
10 changes: 7 additions & 3 deletions src/os_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#ifdef _WIN32
#include <direct.h>
#include <sys/stat.h>
#include <windows.h>
#include <wchar.h>
#include <libavutil/mem.h>
Expand All @@ -48,19 +49,22 @@ static inline int win32_mkdir(const char *filename_utf8)
return ret;
}

static inline int win32_stat(const char *filename_utf8, struct stat* statbuf)
static inline int crip_stat(const char *filename_utf8, struct stat* statbuf)
{
wchar_t *filename_w;
int ret;
if (utf8towchar(filename_utf8, &filename_w))
return -1;
ret = _wstat64(filename_w, (struct _stat64 *)statbuf);
/* Assume struct stat is the same as struct _stat64, which should be true
* because Meson sets _FILE_OFFSET_BITS=64 for mingw64 */
ret = _wstat64(filename_w, statbuf);
av_free(filename_w);
return ret;
}

#define mkdir(path, mode) win32_mkdir(path)
#define stat(path, statbuf) win32_stat(path, statbuf)
#else
#define crip_stat stat
#endif

#if defined(__MACH__)
Expand Down

0 comments on commit cee41bd

Please sign in to comment.