summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--doc/IntObj.38
-rw-r--r--doc/Object.36
-rw-r--r--doc/ObjectType.3110
-rw-r--r--generic/tclPathObj.c19
-rw-r--r--unix/Makefile.in4
6 files changed, 117 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 503dcba..77d92b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2008-06-29 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/ObjectType.3: Updated documentation of the Tcl_ObjType
+ struct to match expectations of Tcl 8.5 [Bug 1917650].
+
+ * generic/tclPathObj.c: Plug memory leak in [Bug 1999176] fix. Thanks
+ Rolf Ade for detecting.
+
+2008-06-28 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclPathObj.c: Plug memory leak in [Bug 1972879] fix. Thanks
+ Rolf Ade for detecting and Dan Steffen for the fix [Bug 2004654].
+
+2008-06-26 Andreas Kupries <andreask@activestate.com>
+
+ * unix/Makefile.in: Followup to my change of 2008-06-25, make code
+ generated by the Makefile and put into the installd tm.tcl
+ conditional on interpreter safeness as well. Thanks to Daniel
+ Steffen for reminding me of that code.
+
2008-06-25 Don Porter <dgp@users.sourceforge.net>
*** 8.5.3 TAGGED FOR RELEASE ***
diff --git a/doc/IntObj.3 b/doc/IntObj.3
index 0a34ea4..5d69303 100644
--- a/doc/IntObj.3
+++ b/doc/IntObj.3
@@ -4,7 +4,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: IntObj.3,v 1.11.6.1 2007/12/13 06:24:10 dgp Exp $
+'\" RCS: @(#) $Id: IntObj.3,v 1.11.6.2 2008/06/30 02:55:00 dgp Exp $
'\"
.so man.macros
.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
@@ -137,15 +137,15 @@ then \fBTCL_ERROR\fR is returned, and if \fIinterp\fR is non-NULL,
an error message is left in \fIinterp\fR. The \fBTcl_ObjType\fR
of \fIobjPtr\fR may be changed to make subsequent calls to the
same routine more efficient. Unlike the other functions,
-\fBTcl_TakeGetBignumFromObj\fR may set the content of the Tcl object
+\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl object
\fIobjPtr\fR to an empty string in the process of retrieving the
multiple-precision integer value.
.PP
The choice between \fBTcl_GetBignumFromObj\fR and
-\fBTcl_TakeGetBignumFromObj\fR is governed by how the caller will
+\fBTcl_TakeBignumFromObj\fR is governed by how the caller will
continue to use \fIobjPtr\fR. If after the \fBmp_int\fR value
is retrieved from \fIobjPtr\fR, the caller will make no more
-use of \fIobjPtr\fR, then using \fBTcl_TakeGetBignumFromObj\fR
+use of \fIobjPtr\fR, then using \fBTcl_TakeBignumFromObj\fR
permits Tcl to detect when an unshared \fIobjPtr\fR permits the
value to be moved instead of copied, which should be more efficient.
If anything later in the caller requires
diff --git a/doc/Object.3 b/doc/Object.3
index 8d5da1a..55678bd 100644
--- a/doc/Object.3
+++ b/doc/Object.3
@@ -4,7 +4,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: Object.3,v 1.15.6.2 2007/11/01 16:25:46 dgp Exp $
+'\" RCS: @(#) $Id: Object.3,v 1.15.6.3 2008/06/30 02:55:00 dgp Exp $
'\"
.so man.macros
.TH Tcl_Obj 3 8.5 Tcl "Tcl Library Procedures"
@@ -102,10 +102,10 @@ reclaim an object's storage.
.PP
Tcl objects are typed.
An object's internal representation is controlled by its type.
-Seven types are predefined in the Tcl core
+Several types are predefined in the Tcl core
including integer, double, list, and bytecode.
Extension writers can extend the set of types
-by using the procedure \fBTcl_RegisterObjType\fR .
+by defining their own \fBTcl_ObjType\fR structs.
.SH "THE TCL_OBJ STRUCTURE"
.PP
Each Tcl object is represented by a \fBTcl_Obj\fR structure
diff --git a/doc/ObjectType.3 b/doc/ObjectType.3
index 0e81777..835383e 100644
--- a/doc/ObjectType.3
+++ b/doc/ObjectType.3
@@ -4,7 +4,7 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: ObjectType.3,v 1.13.6.2 2007/11/01 16:25:46 dgp Exp $
+'\" RCS: @(#) $Id: ObjectType.3,v 1.13.6.3 2008/06/30 02:55:00 dgp Exp $
'\"
.so man.macros
.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
@@ -49,7 +49,10 @@ They are used to register new object types, look up types,
and force conversions from one type to another.
.PP
\fBTcl_RegisterObjType\fR registers a new Tcl object type
-in the table of all object types supported by Tcl.
+in the table of all object types that \fBTcl_GetObjType\fR
+can look up by name. There are other object types supported by Tcl
+as well, which Tcl chooses not to register. Extensions can likewise
+choose to register the object types they create or not.
The argument \fItypePtr\fR points to a Tcl_ObjType structure that
describes the new type by giving its name
and by supplying pointers to four procedures
@@ -60,11 +63,11 @@ it is replaced with the new type.
The Tcl_ObjType structure is described
in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below.
.PP
-\fBTcl_GetObjType\fR returns a pointer to the Tcl_ObjType
+\fBTcl_GetObjType\fR returns a pointer to the registered Tcl_ObjType
with name \fItypeName\fR.
It returns NULL if no type with that name is registered.
.PP
-\fBTcl_AppendAllObjTypes\fR appends the name of each object type
+\fBTcl_AppendAllObjTypes\fR appends the name of each registered object type
as a list element onto the Tcl object referenced by \fIobjPtr\fR.
The return value is \fBTCL_OK\fR unless there was an error
converting \fIobjPtr\fR to a list object;
@@ -74,7 +77,8 @@ in that case \fBTCL_ERROR\fR is returned.
if possible.
It creates a new internal representation for \fIobjPtr\fR
appropriate for the target type \fItypePtr\fR
-and sets its \fItypePtr\fR member to that type.
+and sets its \fItypePtr\fR member as determined by calling the
+\fItypePtr->setFromAnyProc\fR routine.
Any internal representation for \fIobjPtr\fR's old type is freed.
If an error occurs during conversion, it returns \fBTCL_ERROR\fR
and leaves an error message in the result object for \fIinterp\fR
@@ -82,12 +86,23 @@ unless \fIinterp\fR is NULL.
Otherwise, it returns \fBTCL_OK\fR.
Passing a NULL \fIinterp\fR allows this procedure to be used
as a test whether the conversion can be done (and in fact was done).
+.VS 8.5
+.PP
+In many cases, the \fItypePtt->setFromAnyProc\fR routine will
+set \fIobjPtr->typePtr\fR to the argument value \fItypePtr\fR,
+but that is no longer guaranteed. The \fIsetFromAnyProc\fR is
+free to set the internal representation for \fIobjPtr\fR to make
+use of another related Tcl_ObjType, if it sees fit.
+.VE 8.5
.SH "THE TCL_OBJTYPE STRUCTURE"
.PP
Extension writers can define new object types by defining four
-procedures,
-initializing a Tcl_ObjType structure to describe the type,
-and calling \fBTcl_RegisterObjType\fR.
+procedures and
+initializing a Tcl_ObjType structure to describe the type.
+Extension writers may also pass a pointer to their Tcl_ObjType
+structire to \fBTcl_RegisterObjType\fR if they wish to permit
+other extensions to look up their Tcl_ObjType by name with
+the \fBTcl_GetObjType\fR routine.
The \fBTcl_ObjType\fR structure is defined as follows:
.PP
.CS
@@ -102,8 +117,9 @@ typedef struct Tcl_ObjType {
.SS "THE NAME FIELD"
.PP
The \fIname\fR member describes the name of the type, e.g. \fBint\fR.
-Extension writers can look up an object type using its name
-with the \fBTcl_GetObjType\fR procedure.
+When a type is registered, this is the name used by callers
+of \fBTcl_GetObjType\fR to lookup the type. For unregistered
+types, the \fIname\fR field is primarily of value for debugging.
The remaining four members are pointers to procedures
called by the generic Tcl object code:
.SS "THE SETFROMANYPROC FIELD"
@@ -124,22 +140,32 @@ unless \fIinterp\fR is NULL.
If \fIsetFromAnyProc\fR is successful,
it stores the new internal representation,
sets \fIobjPtr\fR's \fItypePtr\fR member to point to
-\fIsetFromAnyProc\fR's \fBTcl_ObjType\fR, and returns \fBTCL_OK\fR.
+the \fBTcl_ObjType\fR struct corresponding to the new
+internal representation, and returns \fBTCL_OK\fR.
Before setting the new internal representation,
the \fIsetFromAnyProc\fR must free any internal representation
of \fIobjPtr\fR's old type;
it does this by calling the old type's \fIfreeIntRepProc\fR
if it is not NULL.
-As an example, the \fIsetFromAnyProc\fR for the built-in Tcl integer type
+.PP
+As an example, the \fIsetFromAnyProc\fR for the built-in Tcl list type
gets an up-to-date string representation for \fIobjPtr\fR
by calling \fBTcl_GetStringFromObj\fR.
-It parses the string to obtain an integer and,
-if this succeeds,
-stores the integer in \fIobjPtr\fR's internal representation
-and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the integer type's
+It parses the string to verify it is in a valid list format and
+to obtain each element value in the list, and, if this succeeds,
+stores the list elements in \fIobjPtr\fR's internal representation
+and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the list type's
Tcl_ObjType structure.
+.PP
Do not release \fIobjPtr\fR's old internal representation unless you
replace it with a new one or reset the \fItypePtr\fR member to NULL.
+.PP
+The \fIsetFromAnyProc\fR member may be set to NULL, if the routines
+making use of the internal representation have no need to derive that
+internal representation from an arbitrary string value. However, in
+this case, passing a pointer to the type to Tcl_ConvertToType() will
+lead to a panic, so to avoid this possibility, the type
+should \fInot\fR be registered.
.SS "THE UPDATESTRINGPROC FIELD"
.PP
The \fIupdateStringProc\fR member contains the address of a function
@@ -153,17 +179,27 @@ typedef void (Tcl_UpdateStringProc) (Tcl_Obj *\fIobjPtr\fR);
\fIobjPtr\fR's \fIbytes\fR member is always NULL when it is called.
It must always set \fIbytes\fR non-NULL before returning.
We require the string representation's byte array
-to have a null after the last byte, at offset \fIlength\fR;
-this allows string representations that do not contain null bytes
+to have a null after the last byte, at offset \fIlength\fR,
+and to have no null bytes before that; this allows string representations
to be treated as conventional null character-terminated C strings.
+These restrictions are easily met by using Tcl's internal UTF encoding
+for the string representation, same as one would do for other
+Tcl routines accepting string values as arguments.
Storage for the byte array must be allocated in the heap by \fBTcl_Alloc\fR
or \fBckalloc\fR. Note that \fIupdateStringProc\fRs must allocate
enough storage for the string's bytes and the terminating null byte.
-The \fIupdateStringProc\fR for Tcl's built-in list type, for example,
-builds an array of strings for each element object
-and then calls \fBTcl_Merge\fR
-to construct a string with proper Tcl list structure.
-It stores this string as the list object's string representation.
+.PP
+The \fIupdateStringProc\fR for Tcl's built-in double type, for example,
+calls Tcl_PrintDouble to write to a buffer of size TCL_DOUBLE_SPACE,
+then allocates and copies the string representation to just enough
+space to hold it. A pointer to the allocated space is stored in
+the \fIbytes\fR member.
+.PP
+The \fIupdateStringProc\fR member may be set to NULL, if the routines
+making use of the internal representation are written so that the
+string representation is never invalidated. Failure to meet this
+obligation will lead to panics or crashes when \fBTcl_GetStringFromObj\fR
+or other similar routines ask for the string representation.
.SS "THE DUPINTREPPROC FIELD"
.PP
The \fIdupIntRepProc\fR member contains the address of a function
@@ -180,12 +216,12 @@ Before the call,
\fIsrcPtr\fR's internal representation is valid and \fIdupPtr\fR's is not.
\fIsrcPtr\fR's object type determines what
copying its internal representation means.
+.PP
For example, the \fIdupIntRepProc\fR for the Tcl integer type
simply copies an integer.
-The built-in list type's \fIdupIntRepProc\fR
-allocates a new array that points at the original element objects;
-the elements are shared between the two lists
-(and their reference counts are incremented to reflect the new references).
+The built-in list type's \fIdupIntRepProc\fR uses a far more
+sophisticated scheme to continue sharing storage as much as it
+reasonably can.
.SS "THE FREEINTREPPROC FIELD"
.PP
The \fIfreeIntRepProc\fR member contains the address of a function
@@ -198,17 +234,19 @@ typedef void (Tcl_FreeInternalRepProc) (Tcl_Obj *\fIobjPtr\fR);
The \fIfreeIntRepProc\fR function can deallocate the storage
for the object's internal representation
and do other type-specific processing necessary when an object is freed.
-For example, Tcl list objects have an \fIinternalRep.otherValuePtr\fR
-that points to an array of pointers to each element in the list.
-The list type's \fIfreeIntRepProc\fR decrements
-the reference count for each element object
-(since the list will no longer refer to those objects),
-then deallocates the storage for the array of pointers.
+.PP
+For example, the list type's \fIfreeIntRepProc\fR respects
+the storage sharing scheme established by the \fIdupIntRepProc\fR
+so that it only frees storage when the last object sharing it
+is being freed.
+.PP
The \fIfreeIntRepProc\fR member can be set to NULL
to indicate that the internal representation does not require freeing.
-The \fIfreeIntRepProc\fR implementation should not access the
-\fIbytes\fR member of the object, as this may potentially have already
-been deleted.
+The \fIfreeIntRepProc\fR implementation must not access the
+\fIbytes\fR member of the object, since Tcl makes its own internal
+uses of that field during object deletion. The defined tasks for
+the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR
+member.
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount
.SH KEYWORDS
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c
index 59ccfbe..ca4ba5c 100644
--- a/generic/tclPathObj.c
+++ b/generic/tclPathObj.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclPathObj.c,v 1.63.2.2 2008/06/25 15:56:13 dgp Exp $
+ * RCS: @(#) $Id: tclPathObj.c,v 1.63.2.3 2008/06/30 02:55:00 dgp Exp $
*/
#include "tclInt.h"
@@ -1602,10 +1602,15 @@ Tcl_FSGetTranslatedPath(
* translated version of cwdPtr to normPathPtr, we'll get the
* translated result we need, and can store it for future use.
*/
- retObj = Tcl_FSJoinToPath(Tcl_FSGetTranslatedPath(interp,
- srcFsPathPtr->cwdPtr), 1, &(srcFsPathPtr->normPathPtr));
+
+ Tcl_Obj *translatedCwdPtr = Tcl_FSGetTranslatedPath(interp,
+ srcFsPathPtr->cwdPtr);
+
+ retObj = Tcl_FSJoinToPath(translatedCwdPtr, 1,
+ &(srcFsPathPtr->normPathPtr));
srcFsPathPtr->translatedPathPtr = retObj;
Tcl_IncrRefCount(retObj);
+ Tcl_DecrRefCount(translatedCwdPtr);
} else {
/*
* It is a pure absolute, normalized path object. This is
@@ -1874,6 +1879,7 @@ Tcl_FSGetNormalizedPath(
if (fsPathPtr->normPathPtr == NULL) {
ClientData clientData = NULL;
Tcl_Obj *useThisCwd = NULL;
+ int pureNormalized = 1;
/*
* Since normPathPtr is NULL, but this is a valid path object, we know
@@ -1922,6 +1928,7 @@ Tcl_FSGetNormalizedPath(
return NULL;
}
+ pureNormalized = 0;
Tcl_DecrRefCount(absolutePath);
absolutePath = Tcl_FSJoinToPath(useThisCwd, 1, &absolutePath);
Tcl_IncrRefCount(absolutePath);
@@ -1941,6 +1948,7 @@ Tcl_FSGetNormalizedPath(
if (absolutePath == NULL) {
return NULL;
}
+ pureNormalized = 0;
#endif /* __WIN32__ */
}
}
@@ -1962,7 +1970,7 @@ Tcl_FSGetNormalizedPath(
* is an absolute path).
*/
- if (useThisCwd == NULL) {
+ if (pureNormalized) {
if (!strcmp(TclGetString(fsPathPtr->normPathPtr),
TclGetString(pathPtr))) {
/*
@@ -1978,7 +1986,8 @@ Tcl_FSGetNormalizedPath(
fsPathPtr->normPathPtr = pathPtr;
}
- } else {
+ }
+ if (useThisCwd != NULL) {
/*
* We just need to free an object we allocated above for relative
* paths (this was returned by Tcl_FSJoinToPath above), and then
diff --git a/unix/Makefile.in b/unix/Makefile.in
index d96c8c0..fc6bf1b 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -4,7 +4,7 @@
# "./configure", which is a configuration script generated by the "autoconf"
# program (constructs like "@foo@" will get replaced in the actual Makefile.
#
-# RCS: @(#) $Id: Makefile.in,v 1.207.2.16 2008/06/25 15:56:20 dgp Exp $
+# RCS: @(#) $Id: Makefile.in,v 1.207.2.17 2008/06/30 02:55:00 dgp Exp $
VERSION = @TCL_VERSION@
MAJOR_VERSION = @TCL_MAJOR_VERSION@
@@ -805,7 +805,7 @@ install-libraries: libraries $(INSTALL_TZDATA) install-msgs
done;
@if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ]; then \
echo "Customizing tcl module path"; \
- echo "::tcl::tm::roots {$(TCL_MODULE_PATH)}" >> \
+ echo "if {![interp issafe]} { ::tcl::tm::roots {$(TCL_MODULE_PATH)} }" >> \
"$(SCRIPT_INSTALL_DIR)"/tm.tcl; \
fi