diff options
author | pooryorick <com.digitalsmarties@pooryorick.com> | 2020-08-12 13:35:00 (GMT) |
---|---|---|
committer | pooryorick <com.digitalsmarties@pooryorick.com> | 2020-08-12 13:35:00 (GMT) |
commit | 478d024dc372e58261448aa2e96a39cca274733b (patch) | |
tree | 7d8ca4dd257c89320d65a0c6b7ffcf0479207e02 | |
parent | 167c883c087ff89c46268d3b3a0067a8095704a5 (diff) | |
parent | 80c4d66b217ec43299960d17a40f07d4cfd870bf (diff) | |
download | tcl-478d024dc372e58261448aa2e96a39cca274733b.zip tcl-478d024dc372e58261448aa2e96a39cca274733b.tar.gz tcl-478d024dc372e58261448aa2e96a39cca274733b.tar.bz2 |
merge bug-3422267ed6b79922
-rw-r--r-- | generic/tclNamesp.c | 7 | ||||
-rw-r--r-- | generic/tclProc.c | 7 | ||||
-rw-r--r-- | tests/interp.test | 37 |
3 files changed, 50 insertions, 1 deletions
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 26dca62..fea23aa 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -959,7 +959,7 @@ Tcl_DeleteNamespace( /* * If the namespace has associated ensemble commands, delete them first. * This leaves the actual contents of the namespace alone (unless they are - * linked ensemble commands, of course). Note that this code is actually + * linked ensemble commands, of course). This code is * reentrant so command delete traces won't purturb things badly. */ @@ -1770,7 +1770,9 @@ DoImport( TclInvokeImportedCmd, InvokeImportedNRCmd, dataPtr, DeleteImportedCmd); dataPtr->realCmdPtr = cmdPtr; + cmdPtr->refCount++; dataPtr->selfPtr = (Command *) importedCmd; + dataPtr->selfPtr->refCount++; dataPtr->selfPtr->compileProc = cmdPtr->compileProc; Tcl_DStringFree(&ds); @@ -1781,6 +1783,7 @@ DoImport( refPtr = (ImportRef *)ckalloc(sizeof(ImportRef)); refPtr->importedCmdPtr = (Command *) importedCmd; + refPtr->importedCmdPtr->refCount++; refPtr->nextPtr = cmdPtr->importRefPtr; cmdPtr->importRefPtr = refPtr; } else { @@ -2076,7 +2079,9 @@ DeleteImportedCmd( } else { prevPtr->nextPtr = refPtr->nextPtr; } + TclCleanupCommandMacro(refPtr->importedCmdPtr); ckfree(refPtr); + TclCleanupCommandMacro(selfPtr) ckfree(dataPtr); return; } diff --git a/generic/tclProc.c b/generic/tclProc.c index 0d67c37..150d036 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -215,6 +215,7 @@ Tcl_ProcObjCmd( */ procPtr->cmdPtr = (Command *) cmd; + procPtr->cmdPtr->refCount++; /* * TIP #280: Remember the line the procedure body is starting on. In a @@ -2154,6 +2155,12 @@ TclProcCleanupProc( ckfree(localPtr); localPtr = nextPtr; } + /* + * TclOOMethod.c:clOOMakeProcMethod sets cmdPtr to NULL + */ + if (procPtr->cmdPtr) { + TclCleanupCommandMacro(procPtr->cmdPtr); + } ckfree(procPtr); /* diff --git a/tests/interp.test b/tests/interp.test index 599ac08..9287756 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -3664,6 +3664,43 @@ test interp-38.8 {interp debug basic setup} -body { } -returnCodes { error } -result {wrong # args: should be "interp debug path ?-frame ?bool??"} + +test interp-39.0 { + no segmentation fault when a command is deleted +} -body { + variable res {} + + proc p1 args { + return success + } + namespace eval ns1 { + namespace export * + } + interp alias {} [namespace current]::ns1::p2 {} [namespace current]::p1 + namespace eval ns2 { + namespace import [namespace parent]::ns1::p2 + } + proc ondelete {oldname newname op} { + variable res + namespace delete ns1 + catch { + ns1::p2 + } res + } + + trace add command ns2::p2 delete [namespace which ondelete] + rename ns2::p2 {} + rename p1 {} + if { + [string match {*invalid command name*ns1::p2*} $res] + } { + return 1 + } else { + return $res + } +} -cleanup { +} -result 1 + # cleanup unset -nocomplain hidden_cmds |