summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--win/tkWinMenu.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index 79642f5..b1bf7f8 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -213,30 +213,36 @@ GetNewID(
TkMenuEntry *mePtr, /* The menu we are working with. */
WORD *menuIDPtr) /* The resulting id. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
- WORD curID = tsdPtr->lastCommandID + 1;
-
- /*
- * The following code relies on WORD wrapping when the highest value is
- * incremented.
- */
+ WORD curID = tsdPtr->lastCommandID;
- while (curID != tsdPtr->lastCommandID) {
+ while (1) {
Tcl_HashEntry *commandEntryPtr;
- int newEntry;
+ int new;
- commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable,
- ((char *) NULL) + curID, &newEntry);
- if (newEntry == 1) {
+ /*
+ * Try the next ID number, taking care to wrap rather than stray
+ * into the system menu IDs. [Bug 3235256]
+ */
+ if (++curID >= 0xF000) {
+ curID = 1;
+ }
+
+ /* Return error when we've checked all IDs without success. */
+ if (curID == tsdPtr->lastCommandID) {
+ return TCL_ERROR;
+ }
+
+ commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable,
+ (char *) curID, &new);
+ if (new) {
Tcl_SetHashValue(commandEntryPtr, mePtr);
*menuIDPtr = curID;
tsdPtr->lastCommandID = curID;
return TCL_OK;
- }
- curID++;
+ }
}
- return TCL_ERROR;
}
/*