summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2020-03-14 21:02:12 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2020-03-14 21:02:12 (GMT)
commit9b8409d9e9bc18ee6c51ddf97223957aa9ac13b1 (patch)
tree3730cf5f9cc507cf0866d25134bd7a540460613c /generic
parent068df4904b6c2f08348f62aa2f06b2103c8aae79 (diff)
parent91484ba1c9b80a2b38909e1ff9500bc7c735a10b (diff)
downloadtcl-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.c69
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++;