diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c index 088880e7..bf5fbfb3 100644 --- a/libtiff/tif_win32.c +++ b/libtiff/tif_win32.c @@ -27,34 +27,38 @@ * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA */ -/* - CreateFileA/CreateFileW return type 'HANDLE'. - - thandle_t is declared like - - DECLARE_HANDLE(thandle_t); - - in tiffio.h. - - Windows (from winnt.h) DECLARE_HANDLE logic looks like - - #ifdef STRICT - typedef void *HANDLE; - #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name - #else - typedef PVOID HANDLE; - #define DECLARE_HANDLE(name) typedef HANDLE name - #endif - - See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64 - builds resulting from this. Unfortunately, the proposed patch was lost. - -*/ - #include "tiffiop.h" #include +/* + CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int', + which is formally incompatible and can even seemingly be of different size: + HANDLE is 64 bit under Win64, while int is still 32 bits there. + + However, only the lower 32 bits of a HANDLE are significant under Win64 as, + for interoperability reasons, they must have the same values in 32- and + 64-bit programs running on the same system, see + + https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication + + Because of this, it is safe to define the following trivial functions for + casting between ints and HANDLEs, which are only really needed to avoid + compiler warnings (and, perhaps, to make the code slightly more clear). + Note that using the intermediate cast to "intptr_t" is crucial for warning + avoidance, as this integer type has the same size as HANDLE in all builds. +*/ + +static inline thandle_t thandle_from_int(int ifd) +{ + return (thandle_t)(intptr_t)ifd; +} + +static inline int thandle_to_int(thandle_t fd) +{ + return (int)(intptr_t)fd; +} + static tmsize_t _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) { @@ -237,7 +241,7 @@ TIFFFdOpen(int ifd, const char* name, const char* mode) break; } } - tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */ + tif = TIFFClientOpen(name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, @@ -282,7 +286,7 @@ TIFFOpen(const char* name, const char* mode) return ((TIFF *)0); } - tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */ + tif = TIFFFdOpen(thandle_to_int(fd), name, mode); if(!tif) CloseHandle(fd); return tif; @@ -337,7 +341,7 @@ TIFFOpenW(const wchar_t* name, const char* mode) NULL, NULL); } - tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */ + tif = TIFFFdOpen(thandle_to_int(fd), (mbname != NULL) ? mbname : "", mode); if(!tif) CloseHandle(fd);