diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-03-14 21:02:12 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-03-14 21:02:12 (GMT) |
commit | 9b8409d9e9bc18ee6c51ddf97223957aa9ac13b1 (patch) | |
tree | 3730cf5f9cc507cf0866d25134bd7a540460613c /generic | |
parent | 068df4904b6c2f08348f62aa2f06b2103c8aae79 (diff) | |
parent | 91484ba1c9b80a2b38909e1ff9500bc7c735a10b (diff) | |
download | tcl-9b8409d9e9bc18ee6c51ddf97223957aa9ac13b1.zip tcl-9b8409d9e9bc18ee6c51ddf97223957aa9ac13b1.tar.gz tcl-9b8409d9e9bc18ee6c51ddf97223957aa9ac13b1.tar.bz2 |
Fix [8f89e2e059aafa1c]: Windows: environment is not reflected properly (special characters). Thanks to sebres for patch and test-case!
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclEnv.c | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 487c1a2..cdae21d 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -34,6 +34,27 @@ static struct { #endif } env; +#if defined(_WIN32) +# define tenviron _wenviron +# define tenviron2utfdstr(tenvstr, len, dstr) \ + Tcl_WinTCharToUtf((TCHAR *)tenvstr, len, dstr) +# define utf2tenvirondstr(str, len, dstr) \ + (const WCHAR *)Tcl_WinUtfToTChar(str, len, dstr) +# define techar WCHAR +# ifdef USE_PUTENV +# define putenv(env) _wputenv((const wchar_t *)env) +# endif +#else +# define tenviron environ +# define tenviron2utfdstr(tenvstr, len, dstr) \ + Tcl_ExternalToUtfDString(NULL, tenvstr, len, dstr) +# define utf2tenvirondstr(str, len, dstr) \ + Tcl_UtfToExternalDString(NULL, str, len, dstr) +# define techar char +#endif + +#define tNTL sizeof(techar) + /* * Declarations for local functions defined in this file: */ @@ -113,16 +134,16 @@ TclSetupEnv( * will hold just the parts to remove. */ - if (environ[0] != NULL) { + if (tenviron[0] != NULL) { int i; Tcl_MutexLock(&envMutex); - for (i = 0; environ[i] != NULL; i++) { + for (i = 0; tenviron[i] != NULL; i++) { Tcl_Obj *obj1, *obj2; const char *p1; char *p2; - p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString); + p1 = tenviron2utfdstr(tenviron[i], -1, &envString); p2 = strchr(p1, '='); if (p2 == NULL) { /* @@ -219,7 +240,7 @@ TclSetEnv( unsigned nameLength, valueLength; int index, length; char *p, *oldValue; - const char *p2; + const techar *p2; /* * Figure out where the entry is going to go. If the name doesn't already @@ -238,18 +259,18 @@ TclSetEnv( * environment is the one we allocated. [Bug 979640] */ - if ((env.ourEnviron != environ) || (length+2 > env.ourEnvironSize)) { + if ((env.ourEnviron != (char *)tenviron) || (length+2 > env.ourEnvironSize)) { char **newEnviron = ckalloc((length + 5) * sizeof(char *)); - memcpy(newEnviron, environ, length * sizeof(char *)); + memcpy(newEnviron, tenviron, length * sizeof(char *)); if ((env.ourEnvironSize != 0) && (env.ourEnviron != NULL)) { ckfree(env.ourEnviron); } - environ = env.ourEnviron = newEnviron; + tenviron = (techar **)(env.ourEnviron = newEnviron); env.ourEnvironSize = length + 5; } index = length; - environ[index + 1] = NULL; + tenviron[index + 1] = NULL; #endif /* USE_PUTENV */ oldValue = NULL; nameLength = strlen(name); @@ -264,7 +285,7 @@ TclSetEnv( * interpreters. */ - oldEnv = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envString); + oldEnv = tenviron2utfdstr(tenviron[index], -1, &envString); if (strcmp(value, oldEnv + (length + 1)) == 0) { Tcl_DStringFree(&envString); Tcl_MutexUnlock(&envMutex); @@ -272,7 +293,7 @@ TclSetEnv( } Tcl_DStringFree(&envString); - oldValue = environ[index]; + oldValue = (char *)tenviron[index]; nameLength = (unsigned) length; } @@ -287,14 +308,14 @@ TclSetEnv( memcpy(p, name, nameLength); p[nameLength] = '='; memcpy(p+nameLength+1, value, valueLength+1); - p2 = Tcl_UtfToExternalDString(NULL, p, -1, &envString); + p2 = utf2tenvirondstr(p, -1, &envString); /* * Copy the native string to heap memory. */ - p = ckrealloc(p, Tcl_DStringLength(&envString) + 1); - memcpy(p, p2, (unsigned) Tcl_DStringLength(&envString) + 1); + p = ckrealloc(p, Tcl_DStringLength(&envString) + tNTL); + memcpy(p, p2, Tcl_DStringLength(&envString) + tNTL); Tcl_DStringFree(&envString); #ifdef USE_PUTENV @@ -305,7 +326,7 @@ TclSetEnv( putenv(p); index = TclpFindVariable(name, &length); #else - environ[index] = p; + tenviron[index] = (techar *)p; #endif /* USE_PUTENV */ /* @@ -314,7 +335,7 @@ TclSetEnv( * string in the cache. */ - if ((index != -1) && (environ[index] == p)) { + if ((index != -1) && (tenviron[index] == (techar *)p)) { ReplaceString(oldValue, p); #ifdef HAVE_PUTENV_THAT_COPIES } else { @@ -440,7 +461,7 @@ TclUnsetEnv( * Remember the old value so we can free it if Tcl created the string. */ - oldValue = environ[index]; + oldValue = (char *)tenviron[index]; /* * Update the system environment. This must be done before we update the @@ -455,19 +476,19 @@ TclUnsetEnv( #if defined(_WIN32) string = ckalloc(length + 2); - memcpy(string, name, (size_t) length); + memcpy(string, name, length); string[length] = '='; string[length+1] = '\0'; #else string = ckalloc(length + 1); - memcpy(string, name, (size_t) length); + memcpy(string, name, length); string[length] = '\0'; #endif /* _WIN32 */ - Tcl_UtfToExternalDString(NULL, string, -1, &envString); - string = ckrealloc(string, Tcl_DStringLength(&envString) + 1); + utf2tenvirondstr(string, -1, &envString); + string = ckrealloc(string, Tcl_DStringLength(&envString) + tNTL); memcpy(string, Tcl_DStringValue(&envString), - (unsigned) Tcl_DStringLength(&envString)+1); + (unsigned) Tcl_DStringLength(&envString) + tNTL); Tcl_DStringFree(&envString); putenv(string); @@ -478,7 +499,7 @@ TclUnsetEnv( * string in the cache. */ - if (environ[index] == string) { + if (tenviron[index] == (techar *)string) { ReplaceString(oldValue, string); #ifdef HAVE_PUTENV_THAT_COPIES } else { @@ -490,7 +511,7 @@ TclUnsetEnv( #endif /* HAVE_PUTENV_THAT_COPIES */ } #else /* !USE_PUTENV_FOR_UNSET */ - for (envPtr = environ+index+1; ; envPtr++) { + for (envPtr = (char *)(tenviron+index+1); ; envPtr++) { envPtr[-1] = *envPtr; if (*envPtr == NULL) { break; @@ -539,7 +560,7 @@ TclGetEnv( if (index != -1) { Tcl_DString envStr; - result = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envStr); + result = tenviron2utfdstr(tenviron[index], -1, &envStr); result += length; if (*result == '=') { result++; |