summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--generic/tkGrid.c134
-rw-r--r--generic/tkWindow.c15
-rw-r--r--tests/grid.test72
4 files changed, 208 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index beaea3e..46e0d77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2006-04-11 Peter Spjuth <peter.spjuth@space.se>
+
+ * generic/tkWindow.c (Tk_NameToWindow): Allow NULL interp to
+ Tk_NameToWindow. This fixes TkGetWindowFromObj which promises to
+ handle NULL but didn't.
+
+ * generic/tkGrid.c: Fixed handling of out of bounds row or column.
+ * tests/grid.test: [Bug 1432666]
+
2006-04-11 Don Porter <dgp@users.sourceforge.net>
* unix/Makefile.in: Updated `make dist` target to be sure the
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index fc68c5b..fa3281b 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.43 2006/04/05 20:54:58 hobbs Exp $
+ * RCS: @(#) $Id: tkGrid.c,v 1.44 2006/04/11 21:52:20 pspjuth Exp $
*/
#include "tkInt.h"
@@ -295,6 +295,10 @@ static Tcl_Obj * NewQuadObj(int, int, int, int);
static int ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
int maxOffset);
static void SetGridSize(Gridder *gridPtr);
+static int SetSlaveColumn(Tcl_Interp *interp, Gridder *slavePtr,
+ int column, int numCols);
+static int SetSlaveRow(Tcl_Interp *interp, Gridder *slavePtr,
+ int row, int numRows);
static void StickyToString(int flags, char *result);
static int StringToSticky(char *string);
static void Unlink(Gridder *gridPtr);
@@ -1039,30 +1043,31 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
}
return TCL_OK;
}
-
+
for (j = 0; j < lObjc; j++) {
int allSlaves = 0;
- if (Tcl_GetIntFromObj(interp, lObjv[j], &slot) == TCL_OK) {
+ if (Tcl_GetIntFromObj(NULL, lObjv[j], &slot) == TCL_OK) {
first = slot;
last = slot;
slavePtr = NULL;
} else if (strcmp(Tcl_GetString(lObjv[j]), "all") == 0) {
/*
- * Reset any lingering error from e.g GetInt.
+ * Make sure master is initialised.
*/
- Tcl_ResetResult(interp);
+
+ InitMasterData(masterPtr);
+
slavePtr = masterPtr->slavePtr;
if (slavePtr == NULL) {
continue;
}
allSlaves = 1;
- } else if (TkGetWindowFromObj(interp, tkwin, lObjv[j], &slave)
+ } else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &slave)
== TCL_OK) {
/*
* Is it gridded in this master?
*/
- Tcl_ResetResult(interp);
slavePtr = GetGrid(slave);
if (slavePtr->masterPtr != masterPtr) {
Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
@@ -1072,7 +1077,6 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv)
return TCL_ERROR;
}
} else {
- Tcl_ResetResult(interp);
Tcl_AppendResult(interp, Tcl_GetString(objv[0]), " ",
Tcl_GetString(objv[1]), ": illegal index \"",
Tcl_GetString(lObjv[j]), "\"", NULL);
@@ -2436,6 +2440,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 --
*
* This internal procedure is used to manage the storage for row and
@@ -2976,7 +3060,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a non-negative integer", NULL);
return TCL_ERROR;
}
- slavePtr->column = tmp;
+ if (SetSlaveColumn(interp, slavePtr, tmp, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
break;
case CONF_COLUMNSPAN:
if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
@@ -2986,7 +3072,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a positive integer", NULL);
return TCL_ERROR;
}
- slavePtr->numCols = tmp;
+ if (SetSlaveColumn(interp, slavePtr, -1, tmp) != TCL_OK) {
+ return TCL_ERROR;
+ }
break;
case CONF_IN:
if (TkGetWindowFromObj(interp, tkwin, objv[i+1],
@@ -3055,7 +3143,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a non-negative integer", NULL);
return TCL_ERROR;
}
- slavePtr->row = tmp;
+ if (SetSlaveRow(interp, slavePtr, tmp, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
break;
case CONF_ROWSPAN:
if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK)
@@ -3065,7 +3155,9 @@ ConfigureSlaves(interp, tkwin, objc, objv)
"\": must be a positive integer", NULL);
return TCL_ERROR;
}
- slavePtr->numRows = tmp;
+ if (SetSlaveRow(interp, slavePtr, -1, tmp) != TCL_OK) {
+ return TCL_ERROR;
+ }
break;
}
}
@@ -3150,11 +3242,18 @@ 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) {
- slavePtr->row = defaultRow;
+ if (SetSlaveRow(interp, slavePtr, defaultRow, -1) != TCL_OK) {
+ return TCL_ERROR;
+ }
}
defaultColumn += slavePtr->numCols;
defaultColumnSpan = 1;
@@ -3238,7 +3337,10 @@ 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/generic/tkWindow.c b/generic/tkWindow.c
index d61e1ec..ad42c6f 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWindow.c,v 1.72 2006/04/05 21:00:00 hobbs Exp $
+ * RCS: @(#) $Id: tkWindow.c,v 1.73 2006/04/11 21:52:20 pspjuth Exp $
*/
#include "tkPort.h"
@@ -2259,7 +2259,8 @@ Tk_SetClassProcs(tkwin, procs, instanceData)
* Results:
* The return result is either a token for the window corresponding to
* "name", or else NULL to indicate that there is no such window. In this
- * case, an error message is left in the interp's result.
+ * case, an error message is left in the interp's result, unless interp
+ * is NULL.
*
* Side effects:
* None.
@@ -2282,15 +2283,19 @@ Tk_NameToWindow(interp, pathName, tkwin)
* we're on our way out of the application.
*/
- Tcl_AppendResult(interp, "NULL main window", NULL);
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "NULL main window", NULL);
+ }
return NULL;
}
hPtr = Tcl_FindHashEntry(&((TkWindow *) tkwin)->mainPtr->nameTable,
pathName);
if (hPtr == NULL) {
- Tcl_AppendResult(interp, "bad window path name \"",
- pathName, "\"", NULL);
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "bad window path name \"",
+ pathName, "\"", NULL);
+ }
return NULL;
}
return (Tk_Window) Tcl_GetHashValue(hPtr);
diff --git a/tests/grid.test b/tests/grid.test
index c58d442..0d8129a 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.27 2006/04/05 20:54:57 hobbs Exp $
+# RCS: @(#) $Id: grid.test,v 1.28 2006/04/11 21:52:20 pspjuth Exp $
package require tcltest 2.1
eval tcltest::configure $argv
@@ -781,6 +781,76 @@ test grid-10.34 {column/row configure - empty 'all' configure} {
destroy $t
} {}
+test grid-10.35 {column/row configure} {
+ # Test that no lingering message is there
+ frame .f
+ set res [grid columnconfigure .f all -weight 1]
+ append res [grid columnconfigure .f {0 all} -weight 1]
+ frame .f.f
+ grid .f.f
+ append res [grid columnconfigure .f {.f.f} -weight 1]
+ append res [grid columnconfigure .f {.f.f 1} -weight 1]
+ append res [grid columnconfigure .f {2 .f.f} -weight 1]
+ destroy .f
+ set res
+} {}
+grid_reset 10.35
+
+test grid-10.36 {column/row configure} {
+ list [catch {grid columnconfigure . all} msg] $msg
+} {1 {expected integer but got "all" (when retreiving options only integer indices are allowed)}}
+grid_reset 10.36
+
+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 ^ -in .} msg] $msg ; update
+ 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} {