From 67e3f2064bffa1c3b92cde8ab9e703e8362d37ee Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 19 Jun 2012 11:58:58 +0000 Subject: make tclWinReg.c compile/run without UNICODE (suggested in bug #3362446) --- win/tclWinReg.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/win/tclWinReg.c b/win/tclWinReg.c index 937089c..aa06e44 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -22,6 +22,13 @@ #endif #include +#ifndef UNICODE +# undef Tcl_WinTCharToUtf +# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) +# undef Tcl_WinUtfToTChar +# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) +#endif + /* * Ensure that we can say which registry is being accessed. */ @@ -611,7 +618,7 @@ GetKeyNames( result = TCL_ERROR; break; } - Tcl_WinTCharToUtf(buffer, bufSize * sizeof(WCHAR), &ds); + Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds); name = Tcl_DStringValue(&ds); if (pattern && !Tcl_StringMatch(name, pattern)) { Tcl_DStringFree(&ds); @@ -898,7 +905,7 @@ GetValueNames( resultPtr = Tcl_NewObj(); Tcl_DStringInit(&buffer); Tcl_DStringSetLength(&buffer, - (int) (maxSize*sizeof(WCHAR))); + (int) (maxSize*sizeof(TCHAR))); index = 0; result = TCL_OK; @@ -1209,7 +1216,7 @@ RecursiveDeleteKey( Tcl_DStringInit(&subkey); Tcl_DStringSetLength(&subkey, - (int) (maxSize * sizeof(WCHAR))); + (int) (maxSize * sizeof(TCHAR))); mode = saveMode; while (result == ERROR_SUCCESS) { -- cgit v0.12 From 869661b25a7665bee7b0d441164b367e4f1aaab7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 19 Jun 2012 13:22:05 +0000 Subject: [bug 3362446]: registry keys command fails with 8.5/8.6 --- win/tclWinReg.c | 94 ++++++++++++++++++--------------------------------------- 1 file changed, 30 insertions(+), 64 deletions(-) diff --git a/win/tclWinReg.c b/win/tclWinReg.c index 3960fda..0b93f3a 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -25,6 +25,14 @@ #define TCL_STORAGE_CLASS DLLEXPORT /* + * The maximum length of a sub-key name. + */ + +#ifndef MAX_KEY_LENGTH +#define MAX_KEY_LENGTH 256 +#endif + +/* * The following macros convert between different endian ints. */ @@ -90,9 +98,6 @@ typedef struct RegWinProcs { DWORD *, BYTE *, DWORD *); LONG (WINAPI *regOpenKeyExProc)(HKEY, CONST TCHAR *, DWORD, REGSAM, HKEY *); - LONG (WINAPI *regQueryInfoKeyProc)(HKEY, TCHAR *, DWORD *, DWORD *, - DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, - FILETIME *); LONG (WINAPI *regQueryValueExProc)(HKEY, CONST TCHAR *, DWORD *, DWORD *, BYTE *, DWORD *); LONG (WINAPI *regSetValueExProc)(HKEY, CONST TCHAR *, DWORD, DWORD, @@ -117,9 +122,6 @@ static RegWinProcs asciiProcs = { DWORD *, BYTE *, DWORD *)) RegEnumValueA, (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, REGSAM, HKEY *)) RegOpenKeyExA, - (LONG (WINAPI *)(HKEY, TCHAR *, DWORD *, DWORD *, - DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, - FILETIME *)) RegQueryInfoKeyA, (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD *, DWORD *, BYTE *, DWORD *)) RegQueryValueExA, (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, DWORD, @@ -142,9 +144,6 @@ static RegWinProcs unicodeProcs = { DWORD *, BYTE *, DWORD *)) RegEnumValueW, (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, REGSAM, HKEY *)) RegOpenKeyExW, - (LONG (WINAPI *)(HKEY, TCHAR *, DWORD *, DWORD *, - DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, - FILETIME *)) RegQueryInfoKeyW, (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD *, DWORD *, BYTE *, DWORD *)) RegQueryValueExW, (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, DWORD, @@ -513,9 +512,7 @@ GetKeyNames( { char *pattern; /* Pattern being matched against subkeys */ HKEY key; /* Handle to the key being examined */ - DWORD subKeyCount; /* Number of subkeys to list */ - DWORD maxSubKeyLen; /* Maximum string length of any subkey */ - char *buffer; /* Buffer to hold the subkey name */ + TCHAR buffer[MAX_KEY_LENGTH*2]; /* Buffer to hold the subkey name */ DWORD bufSize; /* Size of the buffer */ DWORD index; /* Position of the current subkey */ char *name; /* Subkey name */ @@ -537,14 +534,6 @@ GetKeyNames( return TCL_ERROR; } - /* - * Determine how big a buffer is needed for enumerating subkeys, and - * how many subkeys there are - */ - - result = (*regWinProcs->regQueryInfoKeyProc) - (key, NULL, NULL, NULL, &subKeyCount, &maxSubKeyLen, NULL, NULL, - NULL, NULL, NULL, NULL); if (result != ERROR_SUCCESS) { Tcl_SetObjResult(interp, Tcl_NewObj()); Tcl_AppendResult(interp, "unable to query key \"", @@ -553,27 +542,25 @@ GetKeyNames( RegCloseKey(key); return TCL_ERROR; } - if (regWinProcs->useWide) { - buffer = ckalloc((maxSubKeyLen+1) * sizeof(WCHAR)); - } else { - buffer = ckalloc(maxSubKeyLen+1); - } /* Enumerate the subkeys */ resultPtr = Tcl_NewObj(); - for (index = 0; index < subKeyCount; ++index) { - bufSize = maxSubKeyLen+1; + for (index = 0;; ++index) { + bufSize = MAX_KEY_LENGTH; result = (*regWinProcs->regEnumKeyExProc) (key, index, buffer, &bufSize, NULL, NULL, NULL, NULL); if (result != ERROR_SUCCESS) { - Tcl_SetObjResult(interp, Tcl_NewObj()); - Tcl_AppendResult(interp, - "unable to enumerate subkeys of \"", - Tcl_GetString(keyNameObj), - "\": ", NULL); - AppendSystemError(interp, result); - result = TCL_ERROR; + if (result == ERROR_NO_MORE_ITEMS) { + result = TCL_OK; + } else { + Tcl_SetObjResult(interp, Tcl_NewObj()); + Tcl_AppendResult(interp, + "unable to enumerate subkeys of \"", + Tcl_GetString(keyNameObj), "\": ", NULL); + AppendSystemError(interp, result); + result = TCL_ERROR; + } break; } if (regWinProcs->useWide) { @@ -595,9 +582,10 @@ GetKeyNames( } if (result == TCL_OK) { Tcl_SetObjResult(interp, resultPtr); + } else { + Tcl_DecrRefCount(resultPtr); /* BUGFIX: Don't leak on failure. */ } - ckfree(buffer); RegCloseKey(key); return result; } @@ -839,7 +827,7 @@ GetValueNames( { HKEY key; Tcl_Obj *resultPtr; - DWORD index, size, maxSize, result; + DWORD index, size, result; Tcl_DString buffer, ds; char *pattern, *name; @@ -854,27 +842,9 @@ GetValueNames( resultPtr = Tcl_GetObjResult(interp); - /* - * Query the key to determine the appropriate buffer size to hold the - * largest value name plus the terminating null. - */ - - result = (*regWinProcs->regQueryInfoKeyProc)(key, NULL, NULL, NULL, NULL, - NULL, NULL, &index, &maxSize, NULL, NULL, NULL); - if (result != ERROR_SUCCESS) { - Tcl_AppendStringsToObj(resultPtr, "unable to query key \"", - Tcl_GetString(keyNameObj), "\": ", NULL); - AppendSystemError(interp, result); - RegCloseKey(key); - result = TCL_ERROR; - goto done; - } - maxSize++; - - Tcl_DStringInit(&buffer); Tcl_DStringSetLength(&buffer, - (int) ((regWinProcs->useWide) ? maxSize*2 : maxSize)); + (int) ((regWinProcs->useWide) ? MAX_KEY_LENGTH*2 : MAX_KEY_LENGTH)); index = 0; result = TCL_OK; @@ -890,7 +860,7 @@ GetValueNames( * after each iteration because RegEnumValue smashes the old value. */ - size = maxSize; + size = MAX_KEY_LENGTH; while ((*regWinProcs->regEnumValueProc)(key, index, Tcl_DStringValue(&buffer), &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { @@ -912,11 +882,10 @@ GetValueNames( Tcl_DStringFree(&ds); index++; - size = maxSize; + size = MAX_KEY_LENGTH; } Tcl_DStringFree(&buffer); - done: RegCloseKey(key); return result; } @@ -1161,7 +1130,7 @@ RecursiveDeleteKey( CONST char *keyName) /* Name of key to be deleted in external * encoding, not UTF. */ { - DWORD result, size, maxSize; + DWORD result, size; Tcl_DString subkey; HKEY hKey; @@ -1178,23 +1147,20 @@ RecursiveDeleteKey( if (result != ERROR_SUCCESS) { return result; } - result = (*regWinProcs->regQueryInfoKeyProc)(hKey, NULL, NULL, NULL, NULL, - &maxSize, NULL, NULL, NULL, NULL, NULL, NULL); - maxSize++; if (result != ERROR_SUCCESS) { return result; } Tcl_DStringInit(&subkey); Tcl_DStringSetLength(&subkey, - (int) ((regWinProcs->useWide) ? maxSize * 2 : maxSize)); + (int) ((regWinProcs->useWide) ? MAX_KEY_LENGTH * 2 : MAX_KEY_LENGTH)); while (result == ERROR_SUCCESS) { /* * Always get index 0 because key deletion changes ordering. */ - size = maxSize; + size = MAX_KEY_LENGTH; result=(*regWinProcs->regEnumKeyExProc)(hKey, 0, Tcl_DStringValue(&subkey), &size, NULL, NULL, NULL, NULL); if (result == ERROR_NO_MORE_ITEMS) { -- cgit v0.12 From b4274908c29bc7b8e88b1af0b34ba947453ccdbc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 19 Jun 2012 14:55:42 +0000 Subject: Plug memory leak, part of [Bug #3362446] --- ChangeLog | 4 ++++ win/tclWinReg.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6b9c072..5d4d5b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2012-06-19 Jan Nijtmans + + * win/tclWinReg.c: Plug memory leak, part of [Bug #3362446] + 2012-06-08 Don Porter * unix/configure.in: Update autogoo for gettimeofday(). diff --git a/win/tclWinReg.c b/win/tclWinReg.c index 3960fda..7d50996 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -595,6 +595,8 @@ GetKeyNames( } if (result == TCL_OK) { Tcl_SetObjResult(interp, resultPtr); + } else { + Tcl_DecrRefCount(resultPtr); /* BUGFIX: Don't leak on failure. */ } ckfree(buffer); -- cgit v0.12 From c1b361063c982bbd7cc02b0c26c524cc414379e6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 20 Jun 2012 07:38:45 +0000 Subject: add test case for very long value names and values --- tests/registry.test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/registry.test b/tests/registry.test index 85b4f42..a3bc891 100644 --- a/tests/registry.test +++ b/tests/registry.test @@ -458,6 +458,12 @@ test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} { registry delete HKEY_CURRENT_USER\\TclFoobar set result } "foo ba r baz" +test registry-6.21 {GetValue: very long value names and values} {pcOnly} { + registry set HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383] [string repeat x 16383] multi_sz + set result [registry get HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383]] + registry delete HKEY_CURRENT_USER\\TclFoobar + set result +} [string repeat x 16383] test registry-7.1 {GetValueNames: bad key} {pcOnly english} { registry delete HKEY_CURRENT_USER\\TclFoobar -- cgit v0.12 From af21439b8bdd0c25c86c7da8c35b704514557dcc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 20 Jun 2012 13:26:17 +0000 Subject: remove some unused code --- win/tclWinReg.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/win/tclWinReg.c b/win/tclWinReg.c index 0b93f3a..6f99fe1 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -534,15 +534,6 @@ GetKeyNames( return TCL_ERROR; } - if (result != ERROR_SUCCESS) { - Tcl_SetObjResult(interp, Tcl_NewObj()); - Tcl_AppendResult(interp, "unable to query key \"", - Tcl_GetString(keyNameObj), "\": ", NULL); - AppendSystemError(interp, result); - RegCloseKey(key); - return TCL_ERROR; - } - /* Enumerate the subkeys */ resultPtr = Tcl_NewObj(); @@ -1147,9 +1138,6 @@ RecursiveDeleteKey( if (result != ERROR_SUCCESS) { return result; } - if (result != ERROR_SUCCESS) { - return result; - } Tcl_DStringInit(&subkey); Tcl_DStringSetLength(&subkey, @@ -1496,3 +1484,11 @@ ConvertDWORD( localType = (*((char*)(&order)) == 1) ? REG_DWORD : REG_DWORD_BIG_ENDIAN; return (type != localType) ? (DWORD)SWAPLONG(value) : value; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ -- cgit v0.12 From 72e0260dd8c56fb8041518ded09189144ab90b74 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 Jun 2012 17:41:09 +0000 Subject: Remove dead code that complicates fs path values but adds no value. --- generic/tclIOUtil.c | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 40f3f76..bb82d32 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -68,9 +68,9 @@ typedef struct FilesystemRecord { int TclFSCwdPointerEquals _ANSI_ARGS_((Tcl_Obj* objPtr)); int TclFSMakePathFromNormalized _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr, ClientData clientData)); + Tcl_Obj *objPtr)); int TclFSNormalizeToUniquePath _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *pathPtr, int startAt, ClientData *clientDataPtr)); + Tcl_Obj *pathPtr, int startAt)); Tcl_Obj* TclFSMakePathRelative _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *cwdPtr)); Tcl_Obj* TclFSInternalToNormalized _ANSI_ARGS_(( @@ -1376,8 +1376,6 @@ TclFSNormalizeAbsolutePath(interp, pathPtr, clientDataPtr) } } if (nplen > 0) { - ClientData clientData = NULL; - retVal = Tcl_FSJoinPath(split, nplen); /* * Now we have an absolute path, with no '..', '.' sequences, @@ -1391,15 +1389,15 @@ TclFSNormalizeAbsolutePath(interp, pathPtr, clientDataPtr) * other criteria for normalizing a path. */ Tcl_IncrRefCount(retVal); - TclFSNormalizeToUniquePath(interp, retVal, 0, &clientData); + TclFSNormalizeToUniquePath(interp, retVal, 0); /* * Since we know it is a normalized path, we can * actually convert this object into an "path" object for * greater efficiency */ - TclFSMakePathFromNormalized(interp, retVal, clientData); + TclFSMakePathFromNormalized(interp, retVal); if (clientDataPtr != NULL) { - *clientDataPtr = clientData; + *clientDataPtr = NULL; } } else { /* Init to an empty string */ @@ -1456,15 +1454,13 @@ TclFSNormalizeAbsolutePath(interp, pathPtr, clientDataPtr) *--------------------------------------------------------------------------- */ int -TclFSNormalizeToUniquePath(interp, pathPtr, startAt, clientDataPtr) +TclFSNormalizeToUniquePath(interp, pathPtr, startAt) Tcl_Interp *interp; Tcl_Obj *pathPtr; int startAt; - ClientData *clientDataPtr; { FilesystemRecord *fsRecPtr, *firstFsRecPtr; /* Ignore this variable */ - (void)clientDataPtr; /* * Call each of the "normalise path" functions in succession. This is @@ -5347,11 +5343,9 @@ TclFSMakePathRelative(interp, objPtr, cwdPtr) */ int -TclFSMakePathFromNormalized(interp, objPtr, nativeRep) +TclFSMakePathFromNormalized(interp, objPtr) Tcl_Interp *interp; /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr; /* The object to convert. */ - ClientData nativeRep; /* The native rep for the object, if known - * else NULL. */ { FsPath *fsPathPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -5383,7 +5377,7 @@ TclFSMakePathFromNormalized(interp, objPtr, nativeRep) fsPathPtr->translatedPathPtr = NULL; fsPathPtr->normPathPtr = objPtr; fsPathPtr->cwdPtr = NULL; - fsPathPtr->nativePathPtr = nativeRep; + fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsRecPtr = NULL; fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; @@ -5618,7 +5612,6 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) int cwdLen; int pathType; CONST char *cwdStr; - ClientData clientData = NULL; pathType = Tcl_FSGetPathType(fsPathPtr->cwdPtr); dir = Tcl_FSGetNormalizedPath(interp, fsPathPtr->cwdPtr); @@ -5688,8 +5681,7 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) * after that separator. */ - TclFSNormalizeToUniquePath(interp, copy, cwdLen-1, - (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL)); + TclFSNormalizeToUniquePath(interp, copy, cwdLen-1); } /* Now we need to construct the new path object */ @@ -5715,14 +5707,6 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) /* That's our reference to copy used */ Tcl_DecrRefCount(dir); } - if (clientData != NULL) { - /* - * This may be unnecessary. It appears that the - * TclFSNormalizeToUniquePath call above should have already - * set this up. Not changing out of fear of the unknown. - */ - fsPathPtr->nativePathPtr = clientData; - } PATHFLAGS(pathObjPtr) = 0; } /* Ensure cwd hasn't changed */ @@ -5742,7 +5726,6 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) int cwdLen; Tcl_Obj *copy; CONST char *cwdStr; - ClientData clientData = NULL; copy = Tcl_DuplicateObj(fsPathPtr->cwdPtr); Tcl_IncrRefCount(copy); @@ -5780,12 +5763,8 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) * the end of the previously normalized 'dir'. This should * be much faster! */ - TclFSNormalizeToUniquePath(interp, copy, cwdLen-1, - (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL)); + TclFSNormalizeToUniquePath(interp, copy, cwdLen-1); fsPathPtr->normPathPtr = copy; - if (clientData != NULL) { - fsPathPtr->nativePathPtr = clientData; - } } } if (fsPathPtr->normPathPtr == NULL) { -- cgit v0.12 From 52d15b52d02ef41a6a25128de9bd49c2fc59b343 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 Jun 2012 18:22:30 +0000 Subject: ...and one more line. --- generic/tclIOUtil.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index bb82d32..b6f89d9 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1460,7 +1460,6 @@ TclFSNormalizeToUniquePath(interp, pathPtr, startAt) int startAt; { FilesystemRecord *fsRecPtr, *firstFsRecPtr; - /* Ignore this variable */ /* * Call each of the "normalise path" functions in succession. This is -- cgit v0.12 From 38f0b4d80988173806607621adbf9258d555f033 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 Jun 2012 19:36:13 +0000 Subject: Purge more dead fs path code. --- generic/tclIOUtil.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index b6f89d9..94d0a6c 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -98,8 +98,7 @@ static Tcl_PathType GetPathType _ANSI_ARGS_((Tcl_Obj *pathObjPtr, int *driveNameLengthPtr, Tcl_Obj **driveNameRef)); static Tcl_FSPathInFilesystemProc NativePathInFilesystem; static Tcl_Obj* TclFSNormalizeAbsolutePath - _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr, - ClientData *clientDataPtr)); + _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr)); /* * Prototypes for procedures defined later in this file. */ @@ -1337,10 +1336,9 @@ Tcl_FSData(fsPtr) *--------------------------------------------------------------------------- */ static Tcl_Obj * -TclFSNormalizeAbsolutePath(interp, pathPtr, clientDataPtr) +TclFSNormalizeAbsolutePath(interp, pathPtr) Tcl_Interp* interp; /* Interpreter to use */ Tcl_Obj *pathPtr; /* Absolute path to normalize */ - ClientData *clientDataPtr; { int splen = 0, nplen, eltLen, i; char *eltName; @@ -1396,9 +1394,6 @@ TclFSNormalizeAbsolutePath(interp, pathPtr, clientDataPtr) * greater efficiency */ TclFSMakePathFromNormalized(interp, retVal); - if (clientDataPtr != NULL) { - *clientDataPtr = NULL; - } } else { /* Init to an empty string */ retVal = Tcl_NewStringObj("",0); @@ -2538,7 +2533,7 @@ Tcl_FSGetCwd(interp) * could be problematic. */ if (retVal != NULL) { - Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal, NULL); + Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal); if (norm != NULL) { /* * We found a cwd, which is now in our global storage. @@ -2580,7 +2575,7 @@ Tcl_FSGetCwd(interp) if (proc != NULL) { Tcl_Obj *retVal = (*proc)(interp); if (retVal != NULL) { - Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal, NULL); + Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal); /* * Check whether cwd has changed from the value * previously stored in cwdPathPtr. Really 'norm' @@ -5665,7 +5660,7 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) * we avoid [Bug 2385549] ... */ - Tcl_Obj *newCopy = TclFSNormalizeAbsolutePath(interp, copy, NULL); + Tcl_Obj *newCopy = TclFSNormalizeAbsolutePath(interp, copy); Tcl_DecrRefCount(copy); copy = newCopy; } else { @@ -5767,7 +5762,6 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) } } if (fsPathPtr->normPathPtr == NULL) { - ClientData clientData = NULL; Tcl_Obj *useThisCwd = NULL; /* * Since normPathPtr is NULL, but this is a valid path @@ -5854,12 +5848,8 @@ Tcl_FSGetNormalizedPath(interp, pathObjPtr) } } /* Already has refCount incremented */ - fsPathPtr->normPathPtr = TclFSNormalizeAbsolutePath(interp, absolutePath, - (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL)); - if (0 && (clientData != NULL)) { - fsPathPtr->nativePathPtr = - (*fsPathPtr->fsRecPtr->fsPtr->dupInternalRepProc)(clientData); - } + fsPathPtr->normPathPtr + = TclFSNormalizeAbsolutePath(interp, absolutePath); if (!strcmp(Tcl_GetString(fsPathPtr->normPathPtr), Tcl_GetString(pathObjPtr))) { /* -- cgit v0.12 From 989a8101fcd98ea1768732253c10b554aa99f9be Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 21 Jun 2012 10:56:52 +0000 Subject: [Bug 3362446]: possible allocation error when using UNICODE --- win/tclWinReg.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/win/tclWinReg.c b/win/tclWinReg.c index de9f756..ee0c243 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -17,7 +17,6 @@ # define USE_TCL_STUBS #endif #include "tclInt.h" -#include "tclPort.h" #ifdef _MSC_VER # pragma comment (lib, "advapi32.lib") #endif @@ -766,8 +765,8 @@ GetValue( */ Tcl_DStringInit(&data); - length = TCL_DSTRING_STATIC_SIZE - 1; - Tcl_DStringSetLength(&data, (int) length); + Tcl_DStringSetLength(&data, (int) TCL_DSTRING_STATIC_SIZE - 1); + length = TCL_DSTRING_STATIC_SIZE/sizeof(TCHAR) - 1; valueName = Tcl_GetStringFromObj(valueNameObj, &nameLen); nativeValue = Tcl_WinUtfToTChar(valueName, nameLen, &buf); @@ -910,7 +909,7 @@ GetValueNames( size = MAX_KEY_LENGTH; while (RegEnumValue(key,index, (TCHAR *)Tcl_DStringValue(&buffer), &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - size *= 2; + size *= sizeof(TCHAR); Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&buffer), (int) size, &ds); -- cgit v0.12 From b6f50b1321a5cd34af747eb670aad924fc66d7b7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 21 Jun 2012 10:59:15 +0000 Subject: [Bug 3362446]: possible allocation error when using UNICODE --- win/tclWinReg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win/tclWinReg.c b/win/tclWinReg.c index 7d50996..701edfb 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -731,8 +731,8 @@ GetValue( */ Tcl_DStringInit(&data); - length = TCL_DSTRING_STATIC_SIZE - 1; - Tcl_DStringSetLength(&data, (int) length); + Tcl_DStringSetLength(&data, TCL_DSTRING_STATIC_SIZE - 1); + length = TCL_DSTRING_STATIC_SIZE / (regWinProcs->useWide ? 2 : 1) - 1; resultPtr = Tcl_GetObjResult(interp); @@ -748,8 +748,8 @@ GetValue( * Required for HKEY_PERFORMANCE_DATA */ length *= 2; - Tcl_DStringSetLength(&data, (int) length); - result = (*regWinProcs->regQueryValueExProc)(key, (char *) nativeValue, + Tcl_DStringSetLength(&data, (int) length * (regWinProcs->useWide ? 2 : 1)); + result = (*regWinProcs->regQueryValueExProc)(key, (char *) nativeValue, NULL, &type, (BYTE *) Tcl_DStringValue(&data), &length); } Tcl_DStringFree(&buf); -- cgit v0.12 From 687013812cd6ca56d2bfc1c0b75d98a6f8a2d264 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 21 Jun 2012 17:48:37 +0000 Subject: Stop storing FilesystemRecord in the intrep of a "path". We never use it. Store the Tcl_Filesystem instead, which is what we actually need. --- generic/tclFileSystem.h | 7 +----- generic/tclIOUtil.c | 27 +------------------- generic/tclPathObj.c | 65 ++++++++++++++++++------------------------------- 3 files changed, 26 insertions(+), 73 deletions(-) diff --git a/generic/tclFileSystem.h b/generic/tclFileSystem.h index d6e1546..3dfc1de 100644 --- a/generic/tclFileSystem.h +++ b/generic/tclFileSystem.h @@ -68,15 +68,10 @@ MODULE_SCOPE int TclFSNormalizeToUniquePath(Tcl_Interp *interp, Tcl_Obj *pathPtr, int startAt); MODULE_SCOPE Tcl_Obj * TclFSMakePathRelative(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_Obj *cwdPtr); -MODULE_SCOPE Tcl_Obj * TclFSInternalToNormalized( - Tcl_Filesystem *fromFilesystem, - ClientData clientData, - FilesystemRecord **fsRecPtrPtr); MODULE_SCOPE int TclFSEnsureEpochOk(Tcl_Obj *pathPtr, Tcl_Filesystem **fsPtrPtr); MODULE_SCOPE void TclFSSetPathDetails(Tcl_Obj *pathPtr, - FilesystemRecord *fsRecPtr, - ClientData clientData); + Tcl_Filesystem *fsPtr, ClientData clientData); MODULE_SCOPE Tcl_Obj * TclFSNormalizeAbsolutePath(Tcl_Interp *interp, Tcl_Obj *pathPtr); diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index e3c5816..3bdcca3 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -3814,31 +3814,6 @@ Tcl_FSSplitPath( return result; } -/* Simple helper function */ -Tcl_Obj * -TclFSInternalToNormalized( - Tcl_Filesystem *fromFilesystem, - ClientData clientData, - FilesystemRecord **fsRecPtrPtr) -{ - FilesystemRecord *fsRecPtr = FsGetFirstFilesystem(); - - while (fsRecPtr != NULL) { - if (fsRecPtr->fsPtr == fromFilesystem) { - *fsRecPtrPtr = fsRecPtr; - break; - } - fsRecPtr = fsRecPtr->nextPtr; - } - - if ((fsRecPtr != NULL) - && (fromFilesystem->internalToNormalizedProc != NULL)) { - return (*fromFilesystem->internalToNormalizedProc)(clientData); - } else { - return NULL; - } -} - /* *---------------------------------------------------------------------- * @@ -4436,7 +4411,7 @@ Tcl_FSGetFileSystemForPath( * above call to the pathInFilesystemProc. */ - TclFSSetPathDetails(pathPtr, fsRecPtr, clientData); + TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData); retVal = fsRecPtr->fsPtr; } } diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 147c619..7911dea 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -92,9 +92,7 @@ typedef struct FsPath { * generated during the correct filesystem * epoch. The epoch changes when * filesystem-mounts are changed. */ - struct FilesystemRecord *fsRecPtr; - /* Pointer to the filesystem record entry to - * use for this path. */ + Tcl_Filesystem *fsPtr; /* The Tcl_Filesystem that claims this path */ } FsPath; /* @@ -1312,7 +1310,7 @@ TclNewFSPathObj( fsPathPtr->cwdPtr = dirPtr; Tcl_IncrRefCount(dirPtr); fsPathPtr->nativePathPtr = NULL; - fsPathPtr->fsRecPtr = NULL; + fsPathPtr->fsPtr = NULL; fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; SETPATHOBJ(pathPtr, fsPathPtr); @@ -1433,7 +1431,7 @@ TclFSMakePathRelative( * with a recorded cwdPtr context has any actual value. * * Nothing is getting cached. Not normPathPtr, not nativePathPtr, - * nor fsRecPtr, so storing the cwdPtr context against which such + * nor fsPtr, so storing the cwdPtr context against which such * cached values might later be validated appears to be of no * value. Take that away, and all this code is just a mildly * optimized equivalent of a call to SetFsPathFromAny(). That @@ -1482,7 +1480,7 @@ TclFSMakePathRelative( fsPathPtr->cwdPtr = cwdPtr; Tcl_IncrRefCount(cwdPtr); fsPathPtr->nativePathPtr = NULL; - fsPathPtr->fsRecPtr = NULL; + fsPathPtr->fsPtr = NULL; fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; SETPATHOBJ(pathPtr, fsPathPtr); @@ -1592,7 +1590,7 @@ TclFSMakePathFromNormalized( fsPathPtr->normPathPtr = pathPtr; fsPathPtr->cwdPtr = NULL; fsPathPtr->nativePathPtr = NULL; - fsPathPtr->fsRecPtr = NULL; + fsPathPtr->fsPtr = NULL; fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; SETPATHOBJ(pathPtr, fsPathPtr); @@ -1632,14 +1630,14 @@ Tcl_FSNewNativePath( Tcl_Filesystem *fromFilesystem, ClientData clientData) { - Tcl_Obj *pathPtr; + Tcl_Obj *pathPtr = NULL; FsPath *fsPathPtr; - FilesystemRecord *fsFromPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - pathPtr = TclFSInternalToNormalized(fromFilesystem, clientData, - &fsFromPtr); + if (fromFilesystem->internalToNormalizedProc != NULL) { + pathPtr = (*fromFilesystem->internalToNormalizedProc)(clientData); + } if (pathPtr == NULL) { return NULL; } @@ -1670,8 +1668,7 @@ Tcl_FSNewNativePath( fsPathPtr->normPathPtr = pathPtr; fsPathPtr->cwdPtr = NULL; fsPathPtr->nativePathPtr = clientData; - fsPathPtr->fsRecPtr = fsFromPtr; - fsPathPtr->fsRecPtr->fileRefCount++; + fsPathPtr->fsPtr = fromFilesystem; fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; SETPATHOBJ(pathPtr, fsPathPtr); @@ -2128,7 +2125,7 @@ Tcl_FSGetInternalRep( * not easily achievable with the current implementation. */ - if (srcFsPathPtr->fsRecPtr == NULL) { + if (srcFsPathPtr->fsPtr == NULL) { /* * This only usually happens in wrappers like TclpStat which create a * string object and pass it to TclpObjStat. Code which calls the @@ -2148,7 +2145,7 @@ Tcl_FSGetInternalRep( */ srcFsPathPtr = PATHOBJ(pathPtr); - if (srcFsPathPtr->fsRecPtr == NULL) { + if (srcFsPathPtr->fsPtr == NULL) { return NULL; } } @@ -2160,7 +2157,7 @@ Tcl_FSGetInternalRep( * for this is we ask what filesystem this path belongs to. */ - if (fsPtr != srcFsPathPtr->fsRecPtr->fsPtr) { + if (fsPtr != srcFsPathPtr->fsPtr) { const Tcl_Filesystem *actualFs = Tcl_FSGetFileSystemForPath(pathPtr); if (actualFs == fsPtr) { @@ -2173,7 +2170,7 @@ Tcl_FSGetInternalRep( Tcl_FSCreateInternalRepProc *proc; char *nativePathPtr; - proc = srcFsPathPtr->fsRecPtr->fsPtr->createInternalRepProc; + proc = srcFsPathPtr->fsPtr->createInternalRepProc; if (proc == NULL) { return NULL; } @@ -2241,8 +2238,8 @@ TclFSEnsureEpochOk( * Check whether the object is already assigned to a fs. */ - if (srcFsPathPtr->fsRecPtr != NULL) { - *fsPtrPtr = srcFsPathPtr->fsRecPtr->fsPtr; + if (srcFsPathPtr->fsPtr != NULL) { + *fsPtrPtr = srcFsPathPtr->fsPtr; } return TCL_OK; } @@ -2266,7 +2263,7 @@ TclFSEnsureEpochOk( void TclFSSetPathDetails( Tcl_Obj *pathPtr, - FilesystemRecord *fsRecPtr, + Tcl_Filesystem *fsPtr, ClientData clientData) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); @@ -2283,10 +2280,9 @@ TclFSSetPathDetails( } srcFsPathPtr = PATHOBJ(pathPtr); - srcFsPathPtr->fsRecPtr = fsRecPtr; + srcFsPathPtr->fsPtr = fsPtr; srcFsPathPtr->nativePathPtr = clientData; srcFsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; - fsRecPtr->fileRefCount++; } /* @@ -2535,7 +2531,7 @@ SetFsPathFromAny( fsPathPtr->normPathPtr = NULL; fsPathPtr->cwdPtr = NULL; fsPathPtr->nativePathPtr = NULL; - fsPathPtr->fsRecPtr = NULL; + fsPathPtr->fsPtr = NULL; fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; /* @@ -2569,25 +2565,15 @@ FreeFsPathInternalRep( if (fsPathPtr->cwdPtr != NULL) { TclDecrRefCount(fsPathPtr->cwdPtr); } - if (fsPathPtr->nativePathPtr != NULL && fsPathPtr->fsRecPtr != NULL) { + if (fsPathPtr->nativePathPtr != NULL && fsPathPtr->fsPtr != NULL) { Tcl_FSFreeInternalRepProc *freeProc = - fsPathPtr->fsRecPtr->fsPtr->freeInternalRepProc; + fsPathPtr->fsPtr->freeInternalRepProc; if (freeProc != NULL) { (*freeProc)(fsPathPtr->nativePathPtr); fsPathPtr->nativePathPtr = NULL; } } - if (fsPathPtr->fsRecPtr != NULL) { - fsPathPtr->fsRecPtr->fileRefCount--; - if (fsPathPtr->fsRecPtr->fileRefCount <= 0) { - /* - * It has been unregistered already. - */ - - ckfree((char *) fsPathPtr->fsRecPtr); - } - } ckfree((char *) fsPathPtr); pathPtr->typePtr = NULL; @@ -2630,10 +2616,10 @@ DupFsPathInternalRep( copyFsPathPtr->flags = srcFsPathPtr->flags; - if (srcFsPathPtr->fsRecPtr != NULL + if (srcFsPathPtr->fsPtr != NULL && srcFsPathPtr->nativePathPtr != NULL) { Tcl_FSDupInternalRepProc *dupProc = - srcFsPathPtr->fsRecPtr->fsPtr->dupInternalRepProc; + srcFsPathPtr->fsPtr->dupInternalRepProc; if (dupProc != NULL) { copyFsPathPtr->nativePathPtr = @@ -2644,11 +2630,8 @@ DupFsPathInternalRep( } else { copyFsPathPtr->nativePathPtr = NULL; } - copyFsPathPtr->fsRecPtr = srcFsPathPtr->fsRecPtr; + copyFsPathPtr->fsPtr = srcFsPathPtr->fsPtr; copyFsPathPtr->filesystemEpoch = srcFsPathPtr->filesystemEpoch; - if (copyFsPathPtr->fsRecPtr != NULL) { - copyFsPathPtr->fsRecPtr->fileRefCount++; - } copyPtr->typePtr = &tclFsPathType; } -- cgit v0.12