From 1322ffdfde9c03234808a410dcc26e3e6d0b2fd9 Mon Sep 17 00:00:00 2001 From: "jenglish@flightlab.com" Date: Fri, 18 May 2007 21:46:10 +0000 Subject: EntrySetValue: Ensure that widget is in a consistent state before setting the linked -textvariable. Previously, it was possible for [$e index insert] to point past the end of the string, leading to heap corruption [Bug 1721532]. --- ChangeLog | 10 ++++++++++ generic/ttk/ttkEntry.c | 15 ++++++++++----- tests/ttk/entry.test | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5f0c1c4..07d273f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-05-18 Joe English + + * generic/ttk/ttkEntry.c(EntrySetValue): Ensure + that widget is in a consistent state before setting + the linked -textvariable. Previously, it was possible + for [$e index insert] to point past the end of the string, + leading to heap corruption [Bug 1721532]. + * tests/ttk/entry.test(entry-9.1): Add test case + for the above. + 2007-05-18 Don Porter * unix/configure: autoconf-2.59 (FC6 fork) diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index f09e5cf..d41010d 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -1,5 +1,5 @@ /* - * $Id: ttkEntry.c,v 1.8 2007/01/11 19:59:26 jenglish Exp $ + * $Id: ttkEntry.c,v 1.9 2007/05/18 21:46:11 jenglish Exp $ * * DERIVED FROM: tk/generic/tkEntry.c r1.35. * @@ -750,13 +750,15 @@ EntryStoreValue(Entry *entryPtr, const char *value) * linked -textvariable, if any. The write trace on the * text variable is temporarily disabled; however, other * write traces may change the value of the variable. - * If so, the new value is used instead (bypassing validation). + * If so, the widget is updated again with the new value. * * Returns: * TCL_OK if successful, TCL_ERROR otherwise. */ static int EntrySetValue(Entry *entryPtr, const char *value) { + EntryStoreValue(entryPtr, value); + if (entryPtr->entry.textVariableObj) { const char *textVarName = Tcl_GetString(entryPtr->entry.textVariableObj); @@ -765,12 +767,16 @@ static int EntrySetValue(Entry *entryPtr, const char *value) value = Tcl_SetVar(entryPtr->core.interp, textVarName, value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); entryPtr->core.flags &= ~SYNCING_VARIABLE; - if (!value || WidgetDestroyed(&entryPtr->core)) + if (!value || WidgetDestroyed(&entryPtr->core)) { return TCL_ERROR; + } else if (strcmp(value, entryPtr->entry.string) != 0) { + /* Some write trace has changed the variable value. + */ + EntryStoreValue(entryPtr, value); + } } } - EntryStoreValue(entryPtr, value); return TCL_OK; } @@ -1165,7 +1171,6 @@ static GC EntryGetGC(Entry *entryPtr, Tcl_Obj *colorObj) return Tk_GetGC(entryPtr->core.tkwin, mask, &gcValues); } - /* EntryDisplay -- * Redraws the contents of an entry window. */ diff --git a/tests/ttk/entry.test b/tests/ttk/entry.test index 3ac9182..929e856 100644 --- a/tests/ttk/entry.test +++ b/tests/ttk/entry.test @@ -259,4 +259,25 @@ test entry-8.2a "Followup to test 8.2" -body { } -result ::test::foo -cleanup { destroy .e } # For 8.2a, -result {} would also be sensible. +test entry-9.1 "Index range invariants" -setup { + # See bug#1721532 for discussion + proc entry-9.1-trace {n1 n2 op} { + set ::V NO! + } + variable V + trace add variable V write entry-9.1-trace + ttk::entry .e -textvariable V +} -body { + set result [list] + .e insert insert a ; lappend result [.e index insert] [.e index end] + .e insert insert b ; lappend result [.e index insert] [.e index end] + .e insert insert c ; lappend result [.e index insert] [.e index end] + .e insert insert d ; lappend result [.e index insert] [.e index end] + .e insert insert e ; lappend result [.e index insert] [.e index end] + set result +} -result [list 1 3 2 3 3 3 3 3 3 3] -cleanup { + unset V + destroy .e +} + tcltest::cleanupTests -- cgit v0.12