summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--changes4
-rw-r--r--generic/tkGrid.c123
-rw-r--r--tests/grid.test53
4 files changed, 174 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index c40a945..a4e809a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,9 @@
*** 8.4.13 TAGGED FOR RELEASE ***
+ * generic/tkGrid.c: Fixed handling of out of bounds row or column.
+ * tests/grid.test: [Bug 1432666]
+
* changes: Updates for next RC.
2006-04-11 Jeff Hobbs <jeffh@ActiveState.com>
diff --git a/changes b/changes
index 119bb2d..9d34132 100644
--- a/changes
+++ b/changes
@@ -2,7 +2,7 @@ This file summarizes all changes made to Tk since version 1.0 was
released on March 13, 1991. Changes that aren't backward compatible
are marked specially.
-RCS: @(#) $Id: changes,v 1.64.2.37 2006/04/12 15:30:27 dgp Exp $
+RCS: @(#) $Id: changes,v 1.64.2.38 2006/04/12 17:36:25 dgp Exp $
3/16/91 (bug fix) Modified tkWindow.c to remove Tk's Tcl commands from
the interpreter when the main window is deleted (otherwise there will
@@ -5929,4 +5929,6 @@ registered applevents (steffen)
2006-04-11 (bug fix)[1212056] fix panic on safe window exit on Windows (hobbs)
+2006-04-12 (bug fix)[1432666] grid row/col out of bounds crash (spjuth)
+
--- Released 8.4.13, April 19, 2006 --- See ChangeLog for details ---
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index aade17d..373567d 100644
--- a/generic/tkGrid.c
+++ b/generic/tkGrid.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: tkGrid.c,v 1.25.2.4 2006/04/05 19:49:21 hobbs Exp $
+ * RCS: @(#) $Id: tkGrid.c,v 1.25.2.5 2006/04/12 17:35:21 dgp Exp $
*/
#include "tkInt.h"
@@ -289,6 +289,10 @@ static Tcl_Obj *NewQuadObj _ANSI_ARGS_((Tcl_Interp*, int, int, int, int));
static int ResolveConstraints _ANSI_ARGS_((Gridder *gridPtr,
int rowOrColumn, int maxOffset));
static void SetGridSize _ANSI_ARGS_((Gridder *gridPtr));
+static int SetSlaveColumn _ANSI_ARGS_((Tcl_Interp *interp,
+ Gridder *slavePtr, int column, int numCols));
+static int SetSlaveRow _ANSI_ARGS_((Tcl_Interp *interp,
+ Gridder *slavePtr, int row, int numRows));
static void StickyToString _ANSI_ARGS_((int flags, char *result));
static int StringToSticky _ANSI_ARGS_((char *string));
static void Unlink _ANSI_ARGS_((Gridder *gridPtr));
@@ -2185,6 +2189,86 @@ SetGridSize(masterPtr)
}
/*
+ *----------------------------------------------------------------------
+ *
+ * SetSlaveColumn --
+ *
+ * Update column data for a slave, checking that MAX_ELEMENT bound
+ * is not passed.
+ *
+ * Results:
+ * TCL_ERROR if out of bounds, TCL_OK otherwise
+ *
+ * Side effects:
+ * Slave fields are updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetSlaveColumn(
+ Tcl_Interp *interp, /* Interp for error message */
+ Gridder *slavePtr, /* Slave to be updated */
+ int column, /* New column or -1 to be unchanged */
+ int numCols) /* New columnspan or -1 to be unchanged */
+{
+ int newColumn, newNumCols, lastCol;
+
+ newColumn = (column >= 0) ? column : slavePtr->column;
+ newNumCols = (numCols >= 1) ? numCols : slavePtr->numCols;
+
+ lastCol = ((newColumn >= 0) ? newColumn : 0) + newNumCols;
+ if (lastCol >= MAX_ELEMENT) {
+ Tcl_SetResult(interp, "Column out of bounds", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ slavePtr->column = newColumn;
+ slavePtr->numCols = newNumCols;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetSlaveRow --
+ *
+ * Update row data for a slave, checking that MAX_ELEMENT bound
+ * is not passed.
+ *
+ * Results:
+ * TCL_ERROR if out of bounds, TCL_OK otherwise
+ *
+ * Side effects:
+ * Slave fields are updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetSlaveRow(
+ Tcl_Interp *interp, /* Interp for error message */
+ Gridder *slavePtr, /* Slave to be updated */
+ int row, /* New row or -1 to be unchanged */
+ int numRows) /* New rowspan or -1 to be unchanged */
+{
+ int newRow, newNumRows, lastRow;
+
+ newRow = (row >= 0) ? row : slavePtr->row;
+ newNumRows = (numRows >= 1) ? numRows : slavePtr->numRows;
+
+ lastRow = ((newRow >= 0) ? newRow : 0) + newNumRows;
+ if (lastRow >= MAX_ELEMENT) {
+ Tcl_SetResult(interp, "Row out of bounds", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ slavePtr->row = newRow;
+ slavePtr->numRows = newNumRows;
+ return TCL_OK;
+}
+
+/*
*--------------------------------------------------------------
*
* CheckSlotData --
@@ -2669,7 +2753,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a non-negative integer", (char *)NULL);
return TCL_ERROR;
}
- slavePtr->column = tmp;
+ if (SetSlaveColumn(interp, slavePtr, tmp, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
} else if (index == CONF_COLUMNSPAN) {
if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK ||
tmp <= 0) {
@@ -2679,7 +2765,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a positive integer", (char *)NULL);
return TCL_ERROR;
}
- slavePtr->numCols = tmp;
+ if (SetSlaveColumn(interp, slavePtr, -1, tmp) != TCL_OK) {
+ return TCL_ERROR;
+ }
} else if (index == CONF_IN) {
if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
TCL_OK) {
@@ -2735,7 +2823,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a non-negative integer", (char *)NULL);
return TCL_ERROR;
}
- slavePtr->row = tmp;
+ if (SetSlaveRow(interp, slavePtr, tmp, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
} else if (index == CONF_ROWSPAN) {
if ((Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK)
|| tmp <= 0) {
@@ -2746,6 +2836,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
return TCL_ERROR;
}
slavePtr->numRows = tmp;
+ if (SetSlaveRow(interp, slavePtr, -1, tmp) != TCL_OK) {
+ return TCL_ERROR;
+ }
} else if (index == CONF_STICKY) {
int sticky = StringToSticky(Tcl_GetString(objv[i+1]));
if (sticky == -1) {
@@ -2826,14 +2919,26 @@ ConfigureSlaves(interp, tkwin, objc, objv)
*/
if (slavePtr->column == -1) {
- slavePtr->column = defaultColumn;
+ if (SetSlaveColumn(interp, slavePtr, defaultColumn, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+ if (SetSlaveColumn(interp, slavePtr, -1,
+ slavePtr->numCols + defaultColumnSpan - 1) != TCL_OK) {
+ return TCL_ERROR;
}
- slavePtr->numCols += defaultColumnSpan - 1;
if (slavePtr->row == -1) {
if (masterPtr->masterDataPtr == NULL) {
+ if (SetSlaveRow(interp, slavePtr, 0, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
slavePtr->row = 0;
} else {
slavePtr->row = masterPtr->masterDataPtr->rowEnd;
+ if (SetSlaveRow(interp, slavePtr,
+ masterPtr->masterDataPtr->rowEnd, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
}
}
defaultColumn += slavePtr->numCols;
@@ -2915,7 +3020,11 @@ ConfigureSlaves(interp, tkwin, objc, objv)
if (slavePtr->column == lastColumn
&& slavePtr->row + slavePtr->numRows - 1 == lastRow) {
if (slavePtr->numCols <= width) {
- slavePtr->numRows++;
+
+ if (SetSlaveRow(interp, slavePtr, -1,
+ slavePtr->numRows + 1) != TCL_OK) {
+ return TCL_ERROR;
+ }
match++;
j += slavePtr->numCols - 1;
lastWindow = Tk_PathName(slavePtr->tkwin);
diff --git a/tests/grid.test b/tests/grid.test
index 1e07028..ccf2eca 100644
--- a/tests/grid.test
+++ b/tests/grid.test
@@ -5,7 +5,7 @@
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
#
-# RCS: @(#) $Id: grid.test,v 1.17.2.2 2006/04/05 19:49:20 hobbs Exp $
+# RCS: @(#) $Id: grid.test,v 1.17.2.3 2006/04/12 17:35:21 dgp Exp $
package require tcltest 2.1
namespace import -force tcltest::configure
@@ -713,6 +713,57 @@ test grid-10.33 {column/row configure - invalid indices} {
list [catch {grid rowconfigure . {0 1 2} -weight} msg] $msg
} {1 {grid rowconfigure: must specify a single element on retrieval}}
+test grid-10.37 {column/row configure} {
+ list [catch {grid columnconfigure . 100000} msg] $msg
+} {0 {-minsize 0 -pad 0 -uniform {} -weight 0}}
+grid_reset 10.37
+
+test grid-10.38 {column/row configure} -body {
+ # This is a test for bug 1423666 where a column >= 10000 caused
+ # a crash in layout. The update is needed to reach the layout stage.
+ # Test different combinations of row/column overflow
+ frame .f
+ set res {}
+ lappend res [catch {grid .f -row 10 -column 9999} msg] $msg ; update
+ lappend res [catch {grid .f -row 9999 -column 10} msg] $msg ; update
+ lappend res [catch {grid .f -columnspan 2 -column 9998} msg] $msg ; update
+ lappend res [catch {grid .f -rowspan 2 -row 9998} msg] $msg ; update
+ lappend res [catch {grid .f -column 9998 -columnspan 2} msg] $msg ; update
+ lappend res [catch {grid .f -row 9998 -rowspan 2} msg] $msg ; update
+ set res
+} -cleanup {destroy .f} -result [lrange {
+ 1 {Column out of bounds}
+ 1 {Row out of bounds}
+ 1 {Column out of bounds}
+ 1 {Row out of bounds}
+ 1 {Column out of bounds}
+ 1 {Row out of bounds}
+} 0 end]
+grid_reset 10.38
+
+test grid-10.39 {column/row configure} -body {
+ # Additional tests for row/column overflow
+ frame .f
+ frame .g
+ set res {}
+ grid .f -row 9998 -column 0
+ lappend res [catch {grid ^ .g} msg] $msg ; update
+ grid forget .g
+ lappend res [catch {grid .g} msg] $msg ; update
+ grid forget .f .g
+ lappend res [catch {grid .f - -column 9998} msg] $msg ; update
+ grid forget .f .g
+ lappend res [catch {eval grid [string repeat " x " 9999] .f} msg] $msg
+ update
+ set res
+} -cleanup {destroy .f .g} -result [lrange {
+ 1 {Row out of bounds}
+ 1 {Row out of bounds}
+ 1 {Column out of bounds}
+ 1 {Column out of bounds}
+} 0 end]
+grid_reset 10.39
+
# auto-placement tests
test grid-11.1 {default widget placement} {