From 344ec769621fb26f9489a9eaab5647c86fccf046 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 2 Jul 2024 12:22:24 +0000 Subject: Fix for [0de6c1d79c] crash (cherry-picked from trunk) --- generic/tclCmdIL.c | 25 ++++++++++++++++++++++++- tests/info.test | 9 +++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index aef0399..3198cc9 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1160,8 +1160,31 @@ InfoFrameCmd( } corPtr = corPtr->callerEEPtr->corPtr; } - topLevel += (*cmdFramePtrPtr)->level; + if (iPtr->cmdFramePtr == NULL || *cmdFramePtrPtr == NULL) { + if (objc == 1) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(1)); + } else { + if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) { + code = TCL_ERROR; + } else { + Tcl_Obj *objs[2]; + /* + * TODO - "precompiled" is a lie. Chosen only because as documented + * no other fields in the dictionary need be returned. Should + * add a new type like "unknown" meaning no further information + * available. + * TODO - should we check that "level" is 1 ? + */ + TclNewLiteralStringObj(objs[0], "type"); + TclNewLiteralStringObj(objs[1], "precompiled"); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, objs)); + } + } + return code; + } + + topLevel += (*cmdFramePtrPtr)->level; if (topLevel != iPtr->cmdFramePtr->level) { framePtr = iPtr->cmdFramePtr; while (framePtr) { diff --git a/tests/info.test b/tests/info.test index 69be6a3..ff3457f 100644 --- a/tests/info.test +++ b/tests/info.test @@ -2415,6 +2415,15 @@ test info-39.2 {Bug 4b61afd660} -setup { rename probe {} } -result 3 +test info-40.0 {Bug 0de6c1d79c crash} -setup { + interp create child + child hide info +} -cleanup { + interp delete child +} -body { + child invokehidden info frame +} -result 1 + # cleanup catch {namespace delete test_ns_info1 test_ns_info2} ::tcltest::cleanupTests -- cgit v0.12