From 59f808eb7a065aaf628c751e8eb2c7e20505989b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 26 Sep 2018 19:38:08 +0000 Subject: Improvements for zipfs. Document that TclZipfs_AppHook only works on Windows in UNICODE mode. Also, remove this from the stub table because it should never be called this way. Prevent a possible crash on win32 startup. --- doc/zipfs.3 | 4 +++ generic/tcl.decls | 7 +---- generic/tcl.h | 3 ++ generic/tclDecls.h | 1 + generic/tclPlatDecls.h | 27 ----------------- generic/tclStubInit.c | 7 ----- generic/tclZipfs.c | 80 +++++++++++++++++++++++++------------------------- win/tclAppInit.c | 3 +- 8 files changed, 51 insertions(+), 81 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index 7514525..ce5d5eb 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -47,6 +47,10 @@ If a file named \fBmain.tcl\fR is located in that file system, it is treated as the startup script for the process. If the file \fIZIPROOT\fR\fB/app/tcl_library/init.tcl\fR is present, \fBtcl_library\fR is set to \fIZIPROOT\fR\fB/app/tcl_library. .PP +On Windows, \fBTclZipfs_AppHook()\fR has a slightly different signature, it uses +WCHAR in stead of char. As a result, it only works if your application is compiled +using -DUNICODE. +.PP If the \fBtcl_library\fR was not found in the application, the system will then search for it as either a VFS attached to the application dynamic library, or as a zip archive named libtcl_\fIMAJOR\fR_\fIMINOR\fR_\fIpatchLevel\fR.zip either in the present working directory diff --git a/generic/tcl.decls b/generic/tcl.decls index 92e87d6..61247e6 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2365,9 +2365,6 @@ interface tclPlat ################################ # Unix specific functions # (none) -declare 2 unix { - int TclZipfs_AppHook(int *argc, char ***argv) -} ################################ # Windows specific functions @@ -2380,9 +2377,7 @@ declare 0 win { declare 1 win { char *Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr) } -declare 2 win { - int TclZipfs_AppHook(int *argc, TCHAR ***argv) -} + ################################ # Mac OS X specific functions diff --git a/generic/tcl.h b/generic/tcl.h index b44b9c3..2ced16b 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2402,6 +2402,9 @@ EXTERN void Tcl_MainEx(int argc, char **argv, EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact); EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); +#ifndef _WIN32 +EXTERN int TclZipfs_AppHook(int *argc, char ***argv); +#endif /* *---------------------------------------------------------------------------- diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 0449bf1..3fb5355 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3873,6 +3873,7 @@ extern const TclStubs *tclStubsPtr; # define Tcl_MainEx Tcl_MainExW EXTERN void Tcl_MainExW(int argc, wchar_t **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); + EXTERN int TclZipfs_AppHook(int *argc, wchar_t ***argv); #endif #undef TCL_STORAGE_CLASS diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h index ac3f921..abc8ee8 100644 --- a/generic/tclPlatDecls.h +++ b/generic/tclPlatDecls.h @@ -50,12 +50,6 @@ extern "C" { * Exported function declarations: */ -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -/* Slot 0 is reserved */ -/* Slot 1 is reserved */ -/* 2 */ -EXTERN int TclZipfs_AppHook(int *argc, char ***argv); -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, @@ -63,8 +57,6 @@ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, /* 1 */ EXTERN char * Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr); -/* 2 */ -EXTERN int TclZipfs_AppHook(int *argc, TCHAR ***argv); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ @@ -77,28 +69,19 @@ EXTERN int Tcl_MacOSXOpenVersionedBundleResources( const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); -/* 2 */ -EXTERN int TclZipfs_AppHook(int *argc, char ***argv); #endif /* MACOSX */ typedef struct TclPlatStubs { int magic; void *hooks; -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - void (*reserved0)(void); - void (*reserved1)(void); - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 2 */ -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */ char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */ - int (*tclZipfs_AppHook) (int *argc, TCHAR ***argv); /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */ int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */ - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 2 */ #endif /* MACOSX */ } TclPlatStubs; @@ -114,27 +97,17 @@ extern const TclPlatStubs *tclPlatStubsPtr; * Inline function declarations: */ -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -/* Slot 0 is reserved */ -/* Slot 1 is reserved */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define Tcl_WinUtfToTChar \ (tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */ #define Tcl_WinTCharToUtf \ (tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ #define Tcl_MacOSXOpenBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenBundleResources) /* 0 */ #define Tcl_MacOSXOpenVersionedBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* MACOSX */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 6614764..9fa5adb 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -855,20 +855,13 @@ static const TclIntPlatStubs tclIntPlatStubs = { static const TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, 0, -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - 0, /* 0 */ - 0, /* 1 */ - TclZipfs_AppHook, /* 2 */ -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Tcl_WinUtfToTChar, /* 0 */ Tcl_WinTCharToUtf, /* 1 */ - TclZipfs_AppHook, /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ Tcl_MacOSXOpenBundleResources, /* 0 */ Tcl_MacOSXOpenVersionedBundleResources, /* 1 */ - TclZipfs_AppHook, /* 2 */ #endif /* MACOSX */ }; diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 55b854b..19673c8 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -18,10 +18,10 @@ #include "tclInt.h" #include "tclFileSystem.h" -#if !defined(_WIN32) && !defined(_WIN64) -#include -#else +#ifdef _WIN32 #include +#else +#include #endif #include #include @@ -142,19 +142,16 @@ * Windows drive letters. */ -#if defined(_WIN32) || defined(_WIN64) -#define HAS_DRIVES 1 +#ifdef _WIN32 static const char drvletters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#else -#define HAS_DRIVES 0 #endif /* * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(_WIN64) +#ifndef _WIN32 #ifndef HAVE_LOCALTIME_R #ifdef TCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) @@ -173,23 +170,21 @@ typedef struct ZipFile { Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ size_t length; /* Length of memory mapped file */ - unsigned char *tofree; /* Non-NULL if malloc'ed file */ + void *tofree; /* Non-NULL if malloc'ed file */ size_t nfiles; /* Number of files in archive */ size_t baseoffs; /* Archive start */ size_t baseoffsp; /* Password start */ size_t centoffs; /* Archive directory start */ unsigned char pwbuf[264]; /* Password buffer */ -#if defined(_WIN32) || defined(_WIN64) - HANDLE mh; -#endif size_t nopen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ -#if HAS_DRIVES - int mntdrv; /* Drive letter of mount point */ -#endif size_t mntptlen; char *mntpt; /* Mount point */ +#ifdef _WIN32 + HANDLE mh; + int mntdrv; /* Drive letter of mount point */ +#endif } ZipFile; /* @@ -516,7 +511,7 @@ ToDosTime(time_t when) struct tm *tmp, tm; #ifdef TCL_THREADS -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 /* Win32 uses thread local storage */ tmp = localtime(&when); tm = *tmp; @@ -544,7 +539,7 @@ ToDosDate(time_t when) struct tm *tmp, tm; #ifdef TCL_THREADS -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 /* Win32 uses thread local storage */ tmp = localtime(&when); tm = *tmp; @@ -621,7 +616,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA char *path; char *result; int i, j, c, isunc = 0, isvfs=0, n=0; -#if HAS_DRIVES +#ifdef _WIN32 int zipfspath=1; if ( (tail[0] != '\0') @@ -655,7 +650,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA isunc = 1; } } -#if HAS_DRIVES +#ifdef _WIN32 } #endif if(isvfs!=2) { @@ -707,7 +702,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA memcpy(path + i, tail, j); } } -#if HAS_DRIVES +#ifdef _WIN32 for (i = 0; path[i] != '\0'; i++) { if (path[i] == '\\') { path[i] = '/'; @@ -857,13 +852,13 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) if(zf->is_membuf==1) { /* Pointer to memory */ if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); + Tcl_Free(zf->tofree); zf->tofree = NULL; } zf->data = NULL; return; } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 if ((zf->data != NULL) && (zf->tofree == NULL)) { UnmapViewOfFile(zf->data); zf->data = NULL; @@ -878,7 +873,7 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) } #endif if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); + Tcl_Free(zf->tofree); zf->tofree = NULL; } if(zf->chan != NULL) { @@ -1016,7 +1011,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * ClientData handle; zf->namelen=0; zf->is_membuf=0; -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 zf->data = NULL; zf->mh = INVALID_HANDLE_VALUE; #else @@ -1057,7 +1052,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * Tcl_Close(interp, zf->chan); zf->chan = NULL; } else { -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 # ifdef _WIN64 i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER)&zf->length); if ( @@ -1919,8 +1914,8 @@ ZipAddFile( ZipEntry *z; z_stream stream; const char *zpath; - int crc, flush, zpathlen, olen; - size_t nbyte, nbytecompr, len, align = 0; + int crc, flush, zpathlen; + size_t nbyte, nbytecompr, len, olen, align = 0; Tcl_WideInt pos[3]; int mtime = 0, isNew, cmeth; unsigned long keys[3], keys0[3]; @@ -1944,7 +1939,7 @@ ZipAddFile( || (Tcl_SetChannelOption(interp, in, "-translation", "binary") != TCL_OK) || (Tcl_SetChannelOption(interp, in, "-encoding", "binary") != TCL_OK) ) { -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 /* hopefully a directory */ if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { Tcl_Close(interp, in); @@ -2088,13 +2083,14 @@ wrerr: } olen = sizeof (obuf) - stream.avail_out; if (passwd != NULL) { - int i, tmp; + size_t i; + int tmp; for (i = 0; i < olen; i++) { obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); } } - if (olen && (Tcl_Write(out, obuf, olen) != olen)) { + if (olen && ((size_t)Tcl_Write(out, obuf, olen) != olen)) { Tcl_AppendResult(interp, "write error", (char *) NULL); deflateEnd(&stream); Tcl_Close(interp, in); @@ -2873,7 +2869,7 @@ ZipFSListObjCmd( return TCL_OK; } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 #define LIBRARY_SIZE 64 static int ToUtf( @@ -2898,7 +2894,7 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { } else { Tcl_Obj *vfsinitscript; int found=0; -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; @@ -2912,7 +2908,7 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { GetModuleFileNameA(hModule, dllname, MAX_PATH); } else { @@ -4401,12 +4397,15 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ return TCL_ERROR; } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 int TclZipfs_AppHook(int *argc, TCHAR ***argv) #else int TclZipfs_AppHook(int *argc, char ***argv) #endif { +#ifdef _WIN32 + Tcl_DString ds; +#endif /* * Tclkit_MainHook -- * Performs the argument munging for the shell @@ -4442,14 +4441,13 @@ int TclZipfs_AppHook(int *argc, char ***argv) } } } else if (*argc>1) { -#if defined(_WIN32) || defined(_WIN64) - Tcl_DString ds; - strcpy(archive, Tcl_WinTCharToUtf((*argv)[1], -1, &ds)); - Tcl_DStringFree(&ds); + return TCL_OK; +#ifdef _WIN32 + archive = Tcl_WinTCharToUtf((*argv)[1], -1, &ds); #else archive=(*argv)[1]; #endif - if(strcmp(archive,"install")==0) { + if (strcmp(archive,"install")==0) { /* If the first argument is mkzip, run the mkzip program */ Tcl_Obj *vfsinitscript; /* Run this now to ensure the file is present by the time Tcl_Main wants it */ @@ -4483,10 +4481,12 @@ int TclZipfs_AppHook(int *argc, char ***argv) } } } +#ifdef _WIN32 + Tcl_DStringFree(&ds); +#endif } return TCL_OK; } - #ifndef HAVE_ZLIB diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 6d2bda4..6444b21 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -126,7 +126,8 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#else +#elif !defined(_WIN32) && !defined(UNICODE) + /* This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif -- cgit v0.12