summaryrefslogtreecommitdiffstats
path: root/generic/tclIORChan.c
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2024-05-21 10:33:56 (GMT)
committersebres <sebres@users.sourceforge.net>2024-05-21 10:33:56 (GMT)
commitc40badc1d3027d5db084ff9970bf3dc5377c2f0e (patch)
tree816d415cc650bea382fd9210fc280b4460ad4c2e /generic/tclIORChan.c
parentd2433e65fa461c3df0432993584aa77913874c2d (diff)
parent246de88c7debb246492a55e1fc3bfe8f7768a434 (diff)
downloadtcl-c40badc1d3027d5db084ff9970bf3dc5377c2f0e.zip
tcl-c40badc1d3027d5db084ff9970bf3dc5377c2f0e.tar.gz
tcl-c40badc1d3027d5db084ff9970bf3dc5377c2f0e.tar.bz2
merge 8.7
Diffstat (limited to 'generic/tclIORChan.c')
-rw-r--r--generic/tclIORChan.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index 0118ce0..712b67a 100644
--- a/generic/tclIORChan.c
+++ b/generic/tclIORChan.c
@@ -2311,23 +2311,37 @@ NextHandle(void)
return resObj;
}
-static void
-FreeReflectedChannel(
- void *blockPtr)
+static inline void
+CleanRefChannelInstance(
+ ReflectedChannel *rcPtr)
{
- ReflectedChannel *rcPtr = (ReflectedChannel *) blockPtr;
- Channel *chanPtr = (Channel *) rcPtr->chan;
-
- TclChannelRelease((Tcl_Channel)chanPtr);
if (rcPtr->name) {
+ /*
+ * Reset obj-type (channel is deleted or dead anyway) to avoid leakage
+ * by cyclic references (see bug [79474c58800cdf94]).
+ */
+ TclFreeInternalRep(rcPtr->name);
Tcl_DecrRefCount(rcPtr->name);
+ rcPtr->name = NULL;
}
if (rcPtr->methods) {
Tcl_DecrRefCount(rcPtr->methods);
+ rcPtr->methods = NULL;
}
if (rcPtr->cmd) {
Tcl_DecrRefCount(rcPtr->cmd);
+ rcPtr->cmd = NULL;
}
+}
+static void
+FreeReflectedChannel(
+ void *blockPtr)
+{
+ ReflectedChannel *rcPtr = (ReflectedChannel *) blockPtr;
+ Channel *chanPtr = (Channel *) rcPtr->chan;
+
+ TclChannelRelease((Tcl_Channel)chanPtr);
+ CleanRefChannelInstance(rcPtr);
Tcl_Free(rcPtr);
}
@@ -2597,18 +2611,7 @@ MarkDead(
if (rcPtr->dead) {
return;
}
- if (rcPtr->name) {
- Tcl_DecrRefCount(rcPtr->name);
- rcPtr->name = NULL;
- }
- if (rcPtr->methods) {
- Tcl_DecrRefCount(rcPtr->methods);
- rcPtr->methods = NULL;
- }
- if (rcPtr->cmd) {
- Tcl_DecrRefCount(rcPtr->cmd);
- rcPtr->cmd = NULL;
- }
+ CleanRefChannelInstance(rcPtr);
rcPtr->dead = 1;
}