summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjenglish <jenglish@flightlab.com>2007-05-18 21:46:10 (GMT)
committerjenglish <jenglish@flightlab.com>2007-05-18 21:46:10 (GMT)
commit8930fea610db5a00f787a35a28a1f2a43dad6840 (patch)
treedaacf52364071c6ac1bda0b6495d801ab2929071
parent8a5f0dbbec9daac56f2e20b47a49e915fff54e47 (diff)
downloadtk-8930fea610db5a00f787a35a28a1f2a43dad6840.zip
tk-8930fea610db5a00f787a35a28a1f2a43dad6840.tar.gz
tk-8930fea610db5a00f787a35a28a1f2a43dad6840.tar.bz2
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].
-rw-r--r--ChangeLog10
-rw-r--r--generic/ttk/ttkEntry.c15
-rw-r--r--tests/ttk/entry.test21
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 <jenglish@users.sourceforge.net>
+
+ * 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 <dgp@users.sourceforge.net>
* 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