summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-06-21 09:48:03 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-06-21 09:48:03 (GMT)
commit0b65aa03a149454b15064d63aa2043fe094d3016 (patch)
tree9bafb3cbf539e33876ca81fe98aebfcd0e9b79c4
parent103201730d4a0d6ae4285eba46066393dc3a831d (diff)
parentcf052af7a9a777686a38795916133d12e938984e (diff)
downloadtcl-0b65aa03a149454b15064d63aa2043fe094d3016.zip
tcl-0b65aa03a149454b15064d63aa2043fe094d3016.tar.gz
tcl-0b65aa03a149454b15064d63aa2043fe094d3016.tar.bz2
[Bug #3362446]: registry keys command fails with 8.5/8.6
-rw-r--r--ChangeLog6
-rw-r--r--tests/registry.test6
-rw-r--r--win/tclWinReg.c97
3 files changed, 37 insertions, 72 deletions
diff --git a/ChangeLog b/ChangeLog
index 0eea8b1..b84440c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
-2012-06-19 Jan Nijtmans <nijtmans@users.sf.net>
+2012-06-21 Jan Nijtmans <nijtmans@users.sf.net>
- * win/tclWinReg.c: Plug memory leak, part of [Bug #3362446]
- * library/reg/pkgIndex.tcl: Dde version should be 1.3.0, not 1.3
+ * win/tclWinReg.c: [Bug #3362446]: registry keys command fails
+ * tests/registry.test: with 8.5/8.6
2012-06-11 Don Porter <dgp@users.sourceforge.net>
diff --git a/tests/registry.test b/tests/registry.test
index 7234a32..400277f 100644
--- a/tests/registry.test
+++ b/tests/registry.test
@@ -505,6 +505,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} -constraints {win reg english} -setup {
registry delete HKEY_CURRENT_USER\\TclFoobar
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index 475e1d4..de9f756 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -17,6 +17,7 @@
# define USE_TCL_STUBS
#endif
#include "tclInt.h"
+#include "tclPort.h"
#ifdef _MSC_VER
# pragma comment (lib, "advapi32.lib")
#endif
@@ -58,6 +59,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.
*/
@@ -567,10 +576,7 @@ GetKeyNames(
{
const 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 */
- TCHAR *buffer; /* Buffer to hold the subkey name */
- DWORD maxBufSize; /* Maximum size of the buffer */
+ TCHAR buffer[MAX_KEY_LENGTH]; /* Buffer to hold the subkey name */
DWORD bufSize; /* Size of the buffer */
DWORD index; /* Position of the current subkey */
char *name; /* Subkey name */
@@ -594,45 +600,24 @@ GetKeyNames(
}
/*
- * Determine how big a buffer is needed for enumerating subkeys, and how
- * many subkeys there are.
- */
-
- result = RegQueryInfoKey(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 \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
- AppendSystemError(interp, result);
- RegCloseKey(key);
- return TCL_ERROR;
- }
- maxBufSize = maxSubKeyLen + 1;
- buffer = ckalloc(maxBufSize * sizeof(TCHAR));
-
- /*
* Enumerate the subkeys.
*/
resultPtr = Tcl_NewObj();
- for (index = 0; index < subKeyCount; ++index) {
- bufSize = maxBufSize;
+ for (index = 0;; ++index) {
+ bufSize = MAX_KEY_LENGTH;
result = RegEnumKeyEx(key, index, buffer, &bufSize,
NULL, NULL, NULL, NULL);
- if ((result == ERROR_MORE_DATA) && (maxBufSize < MAX_KEY_LENGTH)) {
- maxBufSize = MAX_KEY_LENGTH + 1;
- buffer = ckrealloc(buffer, maxBufSize * sizeof(TCHAR));
- bufSize = maxBufSize;
- result = RegEnumKeyEx(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;
}
Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds);
@@ -654,7 +639,6 @@ GetKeyNames(
Tcl_DecrRefCount(resultPtr); /* BUGFIX: Don't leak on failure. */
}
- ckfree(buffer);
RegCloseKey(key);
return result;
}
@@ -891,7 +875,7 @@ GetValueNames(
{
HKEY key;
Tcl_Obj *resultPtr;
- DWORD index, size, maxSize, result;
+ DWORD index, size, result;
Tcl_DString buffer, ds;
const char *pattern, *name;
@@ -904,27 +888,10 @@ GetValueNames(
return TCL_ERROR;
}
- /*
- * Query the key to determine the appropriate buffer size to hold the
- * largest value name plus the terminating null.
- */
-
- result = RegQueryInfoKey(key, NULL, NULL, NULL, NULL,
- NULL, NULL, &index, &maxSize, NULL, NULL, NULL);
- if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to query key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
- AppendSystemError(interp, result);
- RegCloseKey(key);
- result = TCL_ERROR;
- goto done;
- }
- maxSize++;
-
resultPtr = Tcl_NewObj();
Tcl_DStringInit(&buffer);
Tcl_DStringSetLength(&buffer,
- (int) (maxSize*sizeof(TCHAR)));
+ (int) (MAX_KEY_LENGTH*sizeof(TCHAR)));
index = 0;
result = TCL_OK;
@@ -940,7 +907,7 @@ GetValueNames(
* each iteration because RegEnumValue smashes the old value.
*/
- size = maxSize;
+ size = MAX_KEY_LENGTH;
while (RegEnumValue(key,index, (TCHAR *)Tcl_DStringValue(&buffer),
&size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
size *= 2;
@@ -959,12 +926,10 @@ GetValueNames(
Tcl_DStringFree(&ds);
index++;
- size = maxSize;
+ size = MAX_KEY_LENGTH;
}
Tcl_SetObjResult(interp, resultPtr);
Tcl_DStringFree(&buffer);
-
- done:
RegCloseKey(key);
return result;
}
@@ -1206,7 +1171,7 @@ RecursiveDeleteKey(
* encoding, not UTF. */
REGSAM mode) /* Mode flags to pass. */
{
- DWORD result, size, maxSize;
+ DWORD result, size;
Tcl_DString subkey;
HKEY hKey;
REGSAM saveMode = mode;
@@ -1226,16 +1191,10 @@ RecursiveDeleteKey(
if (result != ERROR_SUCCESS) {
return result;
}
- result = RegQueryInfoKey(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) (maxSize * sizeof(TCHAR)));
+ (int) (MAX_KEY_LENGTH * sizeof(TCHAR)));
mode = saveMode;
while (result == ERROR_SUCCESS) {
@@ -1243,7 +1202,7 @@ RecursiveDeleteKey(
* Always get index 0 because key deletion changes ordering.
*/
- size = maxSize;
+ size = MAX_KEY_LENGTH;
result = RegEnumKeyEx(hKey, 0, (TCHAR *)Tcl_DStringValue(&subkey),
&size, NULL, NULL, NULL, NULL);
if (result == ERROR_NO_MORE_ITEMS) {