From ead37ca168eb29e8afc501d242116547534d619b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 2 Sep 2022 12:35:15 +0000 Subject: Bugfix for TIP #627: If only objProc or deleteProc is updated with Tcl_SetCommandInfo(), for a command registered with Tcl_CreateObjCmd2() ... --- generic/tclBasic.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 645a581..85b74b4 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -2690,26 +2690,30 @@ Tcl_CreateCommand( */ typedef struct { - void *clientData; /* Arbitrary value to pass to object function. */ Tcl_ObjCmdProc2 *proc; - Tcl_ObjCmdProc2 *nreProc; + void *clientData; /* Arbitrary value to pass to proc function. */ Tcl_CmdDeleteProc *deleteProc; + void *deleteData; /* Arbitrary value to pass to deleteProc function. */ + Tcl_ObjCmdProc2 *nreProc; } CmdWrapperInfo; static int cmdWrapperProc(void *clientData, - Tcl_Interp *interp, - int objc, + Tcl_Interp *interp, + int objc, Tcl_Obj * const *objv) { CmdWrapperInfo *info = (CmdWrapperInfo *)clientData; + if (objc < 0) { + objc = -1; + } return info->proc(info->clientData, interp, objc, objv); } static void cmdWrapperDeleteProc(void *clientData) { CmdWrapperInfo *info = (CmdWrapperInfo *)clientData; - clientData = info->clientData; + clientData = info->deleteData; Tcl_CmdDeleteProc *deleteProc = info->deleteProc; ckfree(info); if (deleteProc != NULL) { @@ -2736,8 +2740,9 @@ Tcl_CreateObjCommand2( { CmdWrapperInfo *info = (CmdWrapperInfo *)ckalloc(sizeof(CmdWrapperInfo)); info->proc = proc; - info->deleteProc = deleteProc; info->clientData = clientData; + info->deleteProc = deleteProc; + info->deleteData = clientData; return Tcl_CreateObjCommand(interp, cmdName, (proc ? cmdWrapperProc : NULL), @@ -3380,7 +3385,7 @@ Tcl_SetCommandInfoFromToken( if (cmdPtr->deleteProc == cmdWrapperDeleteProc) { CmdWrapperInfo *info = (CmdWrapperInfo *)cmdPtr->deleteData; info->deleteProc = infoPtr->deleteProc; - info->clientData = infoPtr->deleteData; + info->deleteData = infoPtr->deleteData; } else { cmdPtr->deleteProc = infoPtr->deleteProc; cmdPtr->deleteData = infoPtr->deleteData; @@ -3464,7 +3469,7 @@ Tcl_GetCommandInfoFromToken( if (cmdPtr->deleteProc == cmdWrapperDeleteProc) { CmdWrapperInfo *info = (CmdWrapperInfo *)cmdPtr->deleteData; infoPtr->deleteProc = info->deleteProc; - infoPtr->deleteData = info->clientData; + infoPtr->deleteData = info->deleteData; } else { infoPtr->deleteProc = cmdPtr->deleteProc; infoPtr->deleteData = cmdPtr->deleteData; @@ -9256,9 +9261,10 @@ Tcl_NRCreateCommand2( { CmdWrapperInfo *info = (CmdWrapperInfo *)ckalloc(sizeof(CmdWrapperInfo)); info->proc = proc; + info->clientData = clientData; info->nreProc = nreProc; info->deleteProc = deleteProc; - info->clientData = clientData; + info->deleteData = clientData; return Tcl_NRCreateCommand(interp, cmdName, (proc ? cmdWrapperProc : NULL), (nreProc ? cmdWrapperNreProc : NULL), -- cgit v0.12