summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--tests/menu.test12
-rw-r--r--unix/tkUnixMenu.c42
-rw-r--r--win/tkWinMenu.c6
4 files changed, 43 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index a6bae4c..1691564 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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,