From 53a9169400f29e8f15a30165004b98f337a297a2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 12 Mar 2008 21:22:22 +0000 Subject: [PATCH] Fixed aliasing bug in Windows platform layer (thanks, Dennis!). --- CHANGELOG.txt | 1 + physfs_internal.h | 9 +++++++++ platform/windows.c | 32 +++++++++++++++++++------------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 63dc081..d4c28ce 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,6 +2,7 @@ * CHANGELOG. */ +03122008 - Fixed aliasing bug in Windows platform layer (thanks, Dennis!). 03102008 - Changed some text files from ISO-8859-1 to UTF-8. Replaced all the translations with UTF-8 encoded equivalents. 03082008 - Fixed compiler warnings in Windows platform layer (thanks, Dennis!). diff --git a/physfs_internal.h b/physfs_internal.h index 72586b6..c74fb68 100644 --- a/physfs_internal.h +++ b/physfs_internal.h @@ -33,6 +33,13 @@ extern "C" { #endif +#ifdef __GNUC__ +#define PHYSFS_MINIMUM_GCC_VER(major, minor) \ + ( ((__GNUC__ << 16) + __GNUC_MINOR__) >= (((major) << 16) + (minor)) ) +#else +#define PHYSFS_MINIMUM_GCC_VER(major, minor) (0) +#endif + /* * Interface for small allocations. If you need a little scratch space for * a throwaway buffer or string, use this. It will make small allocations @@ -1020,6 +1027,7 @@ void __PHYSFS_sort(void *entries, PHYSFS_uint32 max, #define __PHYSFS_UI64(x) x #endif + /* * Check if a ui64 will fit in the platform's address space. * The initial sizeof check will optimize this macro out entirely on @@ -1032,6 +1040,7 @@ void __PHYSFS_sort(void *entries, PHYSFS_uint32 max, ((s) > (__PHYSFS_UI64(0xFFFFFFFFFFFFFFFF) >> (64-(sizeof(size_t)*8)))) \ ) + /* * This is a strcasecmp() or stricmp() replacement that expects both strings * to be in UTF-8 encoding. It will do "case folding" to decide if the diff --git a/platform/windows.c b/platform/windows.c index b0ec81b..b4096ad 100644 --- a/platform/windows.c +++ b/platform/windows.c @@ -256,10 +256,21 @@ static HANDLE WINAPI fallbackCreateFileW(LPCWSTR fname, } /* fallbackCreateFileW */ -/* A blatant abuse of pointer casting... */ -static int symLookup(HMODULE dll, void **addr, const char *sym) +#if (PHYSFS_MINIMUM_GCC_VERSION(3,3)) + typedef FARPROC __attribute__((__may_alias__)) PHYSFS_FARPROC; +#else + typedef FARPROC PHYSFS_FARPROC; +#endif + + +static void symLookup(HMODULE dll, PHYSFS_FARPROC *addr, const char *sym, + int reallyLook, PHYSFS_FARPROC fallback) { - return( (*addr = GetProcAddress(dll, sym)) != NULL ); + PHYSFS_FARPROC proc; + proc = (PHYSFS_FARPROC) ((reallyLook) ? GetProcAddress(dll, sym) : NULL); + if (proc == NULL) + proc = fallback; /* may also be NULL. */ + *addr = proc; } /* symLookup */ @@ -267,17 +278,12 @@ static int findApiSymbols(void) { HMODULE dll = NULL; - #define LOOKUP_NOFALLBACK(x, reallyLook) { \ - if (reallyLook) \ - symLookup(dll, (void **) &p##x, #x); \ - else \ - p##x = NULL; \ - } + #define LOOKUP_NOFALLBACK(x, reallyLook) \ + symLookup(dll, (PHYSFS_FARPROC *) &p##x, #x, reallyLook, NULL) - #define LOOKUP(x, reallyLook) { \ - if ((!reallyLook) || (!symLookup(dll, (void **) &p##x, #x))) \ - p##x = fallback##x; \ - } + #define LOOKUP(x, reallyLook) \ + symLookup(dll, (PHYSFS_FARPROC *) &p##x, #x, \ + reallyLook, (PHYSFS_FARPROC) fallback##x) /* Apparently Win9x HAS the Unicode entry points, they just don't WORK. */ /* ...so don't look them up unless we're on NT+. (see osHasUnicode.) */