diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | tests/menu.test | 12 | ||||
-rw-r--r-- | unix/tkUnixMenu.c | 42 | ||||
-rw-r--r-- | win/tkWinMenu.c | 6 |
4 files changed, 43 insertions, 22 deletions
@@ -1,3 +1,8 @@ +2006-11-24 Jeff Hobbs <jeffh@ActiveState.com> + + * unix/tkUnixMenu.c (DrawMenuUnderline): bound Tcl_UtfAtIndex usage + * tests/menu.test (menu-36.1): [Bug 1599877] + 2006-11-23 Jeff Hobbs <jeffh@ActiveState.com> * win/tkWinMenu.c (TkWinHandleMenuEvent, DrawMenuUnderline): diff --git a/tests/menu.test b/tests/menu.test index ed60a38..c9d33a9 100644 --- a/tests/menu.test +++ b/tests/menu.test @@ -5,7 +5,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: menu.test,v 1.13.2.1 2003/07/15 13:59:06 vincentdarley Exp $ +# RCS: @(#) $Id: menu.test,v 1.13.2.2 2006/11/24 18:11:54 hobbs Exp $ package require tcltest 2.1 namespace import -force tcltest::configure @@ -2486,6 +2486,16 @@ test menu-35.1 {menus on multiple screens - crashes tk8.3.1, Bug 5454} \ destroy .two } {} +test menu-36.1 {menu -underline string overruns Bug 1599877} {} { + # ensure that -underline does not do string overruns [Bug 1599877] + catch {destroy .m} + menu .m + .m add command -label "File" -underline [expr {1<<30}] + . configure -menu .m + update + tk::TraverseToMenu . "e" +} {} + # cleanup deleteWindows ::tcltest::cleanupTests diff --git a/unix/tkUnixMenu.c b/unix/tkUnixMenu.c index cec9ad6..a3a0c75 100644 --- a/unix/tkUnixMenu.c +++ b/unix/tkUnixMenu.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixMenu.c,v 1.7.2.1 2004/05/03 23:23:42 hobbs Exp $ + * RCS: @(#) $Id: tkUnixMenu.c,v 1.7.2.2 2006/11/24 18:11:54 hobbs Exp $ */ #include "tkPort.h" @@ -884,26 +884,32 @@ DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) int width; int height; { - int indicatorSpace = mePtr->indicatorSpace; + if ((mePtr->underline >= 0) && (mePtr->labelPtr != NULL)) { + int len; - if (mePtr->underline >= 0) { - int activeBorderWidth; - int leftEdge; - char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); - CONST char *start = Tcl_UtfAtIndex(label, mePtr->underline); - CONST char *end = Tcl_UtfNext(start); + /* do the unicode call just to prevent overruns */ + Tcl_GetUnicodeFromObj(mePtr->labelPtr, &len); + if (mePtr->underline < len) { + int activeBorderWidth; + int leftEdge; + CONST char *label, *start, *end; - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - leftEdge = x + indicatorSpace + activeBorderWidth; - if (menuPtr->menuType == MENUBAR) { - leftEdge += 5; - } + label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + start = Tcl_UtfAtIndex(label, mePtr->underline); + end = Tcl_UtfNext(start); - Tk_UnderlineChars(menuPtr->display, d, gc, tkfont, label, - leftEdge, y + (height + fmPtr->ascent - fmPtr->descent) / 2, - start - label, end - label); - } + Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, + menuPtr->activeBorderWidthPtr, &activeBorderWidth); + leftEdge = x + mePtr->indicatorSpace + activeBorderWidth; + if (menuPtr->menuType == MENUBAR) { + leftEdge += 5; + } + + Tk_UnderlineChars(menuPtr->display, d, gc, tkfont, label, leftEdge, + y + (height + fmPtr->ascent - fmPtr->descent) / 2, + start - label, end - label); + } + } } /* diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index 8bd4e16..5394353 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinMenu.c,v 1.21.2.7 2006/11/24 01:52:08 hobbs Exp $ + * RCS: @(#) $Id: tkWinMenu.c,v 1.21.2.8 2006/11/24 18:11:54 hobbs Exp $ */ #define OEMRESOURCE @@ -1059,7 +1059,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) Tcl_GetUnicodeFromObj(labelPtr, &len); if (underline < len) { char *label; - label = Tcl_GetStringFromObj(labelPtr, &len); + label = Tcl_GetStringFromObj(labelPtr, NULL); if (CharUpper((LPTSTR) menuChar) == CharUpper((LPTSTR) *Tcl_UtfAtIndex(label, underline))) { @@ -1833,7 +1833,7 @@ DrawMenuUnderline( if (mePtr->underline < len) { CONST char *label, *start, *end; - label = Tcl_GetStringFromObj(mePtr->labelPtr, &len); + label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); start = Tcl_UtfAtIndex(label, mePtr->underline); end = Tcl_UtfNext(start); Tk_UnderlineChars(menuPtr->display, d, |