summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--generic/tclObj.c19
-rw-r--r--generic/tclStringObj.c15
3 files changed, 26 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f0aa06..07c2111 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,12 @@
2009-02-10 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclObj.c (Tcl_GetString): Added comments and validity
+ checks following the call to an UpdateStringProc.
+
* generic/tclStringObj.c: Reduce code duplication in Tcl_GetUnicode*.
Restrict AppendUtfToUtfRep to non-negative length appends.
Convert all Tcl_InvalidateStringRep() calls into macros.
+ Simplify Tcl_AttemptSetObjLength by removing unreachable code.
2009-02-09 Jan Nijtmans <nijtmans@users.sf.net>
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 72de8f4..56d42a6 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclObj.c,v 1.149 2009/02/03 18:16:07 dkf Exp $
+ * RCS: @(#) $Id: tclObj.c,v 1.150 2009/02/10 17:09:09 dgp Exp $
*/
#include "tclInt.h"
@@ -1068,11 +1068,28 @@ Tcl_GetString(
return objPtr->bytes;
}
+ /*
+ * Note we do not check for objPtr->typePtr == NULL. An invariant of
+ * a properly maintained Tcl_Obj is that at least one of objPtr->bytes
+ * and objPtr->typePtr must not be NULL. If broken extensions fail to
+ * maintain that invariant, we can crash here.
+ */
+
if (objPtr->typePtr->updateStringProc == NULL) {
+ /*
+ * Those Tcl_ObjTypes which choose not to define an updateStringProc
+ * must be written in such a way that (objPtr->bytes) never becomes
+ * NULL. This panic was added in Tcl 8.1.
+ */
Tcl_Panic("UpdateStringProc should not be invoked for type %s",
objPtr->typePtr->name);
}
objPtr->typePtr->updateStringProc(objPtr);
+ if (objPtr->bytes == NULL || objPtr->length < 0
+ || objPtr->bytes[objPtr->length] != '\0') {
+ Tcl_Panic("UpdateStringProc for type '%s' "
+ "failed to create a valid string rep", objPtr->typePtr->name);
+ }
return objPtr->bytes;
}
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 2b0157e..eef8b1d 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -33,7 +33,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclStringObj.c,v 1.90 2009/02/10 15:37:19 dgp Exp $ */
+ * RCS: @(#) $Id: tclStringObj.c,v 1.91 2009/02/10 17:09:09 dgp Exp $ */
#include "tclInt.h"
#include "tommath.h"
@@ -930,18 +930,11 @@ Tcl_AttemptSetObjLength(
if (objPtr->bytes != tclEmptyStringRep) {
newBytes = attemptckrealloc(objPtr->bytes, (unsigned) length+1);
- if (newBytes == NULL) {
- return 0;
- }
} else {
newBytes = attemptckalloc((unsigned) length+1);
- if (newBytes == NULL) {
- return 0;
- }
- if (objPtr->bytes != NULL && objPtr->length != 0) {
- memcpy(newBytes, objPtr->bytes, (size_t) objPtr->length);
- TclInvalidateStringRep(objPtr);
- }
+ }
+ if (newBytes == NULL) {
+ return 0;
}
objPtr->bytes = newBytes;
stringPtr->allocated = length;