summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2011-12-22 18:39:16 (GMT)
committerdgp <dgp@users.sourceforge.net>2011-12-22 18:39:16 (GMT)
commitbcc8f53d1fdf9c82b0d1b4dc17a5dfeb3038edf9 (patch)
treee095e972a2160ac9b7666f095eb2990f155fe217 /win
parent7c0ca69d2510691fb2f0644a3146e9d9d2d90d0a (diff)
downloadtk-bcc8f53d1fdf9c82b0d1b4dc17a5dfeb3038edf9.zip
tk-bcc8f53d1fdf9c82b0d1b4dc17a5dfeb3038edf9.tar.gz
tk-bcc8f53d1fdf9c82b0d1b4dc17a5dfeb3038edf9.tar.bz2
3235256 - Keep menu entry IDs out of system values. Thanks Colin McDonald.
Diffstat (limited to 'win')
-rw-r--r--win/tkWinMenu.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index fe6132f..b992b04 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -197,38 +197,35 @@ GetNewID(mePtr, menuIDPtr)
TkMenuEntry *mePtr; /* The menu we are working with */
WORD *menuIDPtr; /* The resulting id */
{
- int found = 0;
- int newEntry;
- Tcl_HashEntry *commandEntryPtr;
- WORD returnID;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ WORD curID = tsdPtr->lastCommandID;
- WORD curID = tsdPtr->lastCommandID + 1;
+ while (1) {
+ Tcl_HashEntry *commandEntryPtr;
+ int new;
- /*
- * The following code relies on WORD wrapping when the highest value is
- * incremented.
- */
-
- while (curID != tsdPtr->lastCommandID) {
- commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable,
- (char *) curID, &newEntry);
- if (newEntry == 1) {
- found = 1;
- returnID = curID;
- break;
- }
- curID++;
- }
+ /*
+ * Try the next ID number, taking care to wrap rather than stray
+ * into the system menu IDs. [Bug 3235256]
+ */
+ if (++curID >= 0xF000) {
+ curID = 1;
+ }
- if (found) {
- Tcl_SetHashValue(commandEntryPtr, (char *) mePtr);
- *menuIDPtr = returnID;
- tsdPtr->lastCommandID = returnID;
- return TCL_OK;
- } else {
- return TCL_ERROR;
+ /* 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, (char *) mePtr);
+ *menuIDPtr = curID;
+ tsdPtr->lastCommandID = curID;
+ return TCL_OK;
+ }
}
}