summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpooryorick <com.digitalsmarties@pooryorick.com>2021-09-02 23:03:07 (GMT)
committerpooryorick <com.digitalsmarties@pooryorick.com>2021-09-02 23:03:07 (GMT)
commitdff41a451d6d474fceb935decbcef5794ecd20ff (patch)
treea9400c49dcefd1f395f3deb3b749886be2fdb5a0
parent975416ffc016b64aa500f81e21deabc1e0b56cda (diff)
downloadtcl-dff41a451d6d474fceb935decbcef5794ecd20ff.zip
tcl-dff41a451d6d474fceb935decbcef5794ecd20ff.tar.gz
tcl-dff41a451d6d474fceb935decbcef5794ecd20ff.tar.bz2
Merge fixes for [ccc448a6bfd5], namespace ensemble subcommand name prefix
matching and a subsequent error results in a segmentation fault.
-rw-r--r--generic/tclEnsemble.c20
-rw-r--r--generic/tclIndexObj.c18
-rw-r--r--generic/tclInt.h4
-rw-r--r--tests/namespace.test18
4 files changed, 44 insertions, 16 deletions
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
index ea32e8a..7f47510 100644
--- a/generic/tclEnsemble.c
+++ b/generic/tclEnsemble.c
@@ -2193,6 +2193,18 @@ TclSpellFix(
TclNRAddCallback(interp, TclNRReleaseValues, fix, NULL, NULL, NULL);
}
+Tcl_Obj *const *TclEnsembleGetRewriteValues(
+ Tcl_Interp *interp /* Current interpreter. */
+)
+{
+ Interp *iPtr = (Interp *) interp;
+ Tcl_Obj *const *origObjv = iPtr->ensembleRewrite.sourceObjs;
+ if (origObjv[0] == NULL) {
+ origObjv = (Tcl_Obj *const *)origObjv[2];
+ }
+ return origObjv;
+}
+
/*
*----------------------------------------------------------------------
*
@@ -2217,12 +2229,18 @@ TclFetchEnsembleRoot(
int objc,
int *objcPtr)
{
+ Tcl_Obj *const *sourceObjs;
Interp *iPtr = (Interp *) interp;
if (iPtr->ensembleRewrite.sourceObjs) {
*objcPtr = objc + iPtr->ensembleRewrite.numRemovedObjs
- iPtr->ensembleRewrite.numInsertedObjs;
- return iPtr->ensembleRewrite.sourceObjs;
+ if (iPtr->ensembleRewrite.sourceObjs[0] == NULL) {
+ sourceObjs = (Tcl_Obj *const *)iPtr->ensembleRewrite.sourceObjs[1];
+ } else {
+ sourceObjs = iPtr->ensembleRewrite.sourceObjs;
+ }
+ return sourceObjs;
}
*objcPtr = objc;
return objv;
diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c
index d7dfb71..bdcd653 100644
--- a/generic/tclIndexObj.c
+++ b/generic/tclIndexObj.c
@@ -882,27 +882,19 @@ Tcl_WrongNumArgs(
}
/*
- * Check to see if we are processing an ensemble implementation, and if so
- * rewrite the results in terms of how the ensemble was invoked.
+ * If processing an an ensemble implementation, rewrite the results in
+ * terms of how the ensemble was invoked.
*/
if (iPtr->ensembleRewrite.sourceObjs != NULL) {
int toSkip = iPtr->ensembleRewrite.numInsertedObjs;
int toPrint = iPtr->ensembleRewrite.numRemovedObjs;
- Tcl_Obj *const *origObjv = iPtr->ensembleRewrite.sourceObjs;
+ Tcl_Obj *const *origObjv = TclEnsembleGetRewriteValues(interp);
/*
- * Check for spelling fixes, and substitute the fixed values.
- */
-
- if (origObjv[0] == NULL) {
- origObjv = (Tcl_Obj *const *)origObjv[2];
- }
-
- /*
- * We only know how to do rewriting if all the replaced objects are
+ * Only do rewrite the command if all the replaced objects are
* actually arguments (in objv) to this function. Otherwise it just
- * gets too complicated and we'd be better off just giving a slightly
+ * gets too complicated and it's to just give a slightly
* confusing error message...
*/
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 9fec41e..dc6b83f 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2941,8 +2941,8 @@ MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr,
MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr);
MODULE_SCOPE Tcl_Obj *const * TclFetchEnsembleRoot(Tcl_Interp *interp,
Tcl_Obj *const *objv, int objc, int *objcPtr);
-MODULE_SCOPE Tcl_Namespace * TclEnsureNamespace(
- Tcl_Interp *interp,
+MODULE_SCOPE Tcl_Obj *const *TclEnsembleGetRewriteValues(Tcl_Interp *interp);
+MODULE_SCOPE Tcl_Namespace *TclEnsureNamespace(Tcl_Interp *interp,
Tcl_Namespace *namespacePtr);
MODULE_SCOPE void TclFinalizeAllocSubsystem(void);
diff --git a/tests/namespace.test b/tests/namespace.test
index e585504..08531e4 100644
--- a/tests/namespace.test
+++ b/tests/namespace.test
@@ -1846,6 +1846,24 @@ test namespace-42.10 {
unset -nocomplain lst
} -returnCodes error -match glob -result {invalid command name *three*}
+
+test namespace-42.11 {
+ ensembles: prefix matching segmentation fault
+
+ issue ccc448a6bfd59cbd
+} -body {
+ namespace eval n1 {
+ namespace ensemble create
+ namespace export *
+ proc p1 args {error success}
+ }
+ # segmentation fault only occurs in the non-byte-compiled path, so avoid
+ # byte compilation
+ set cmd {namespace eva n1 {[namespace parent]::n1 p1}}
+ {*}$cmd
+} -returnCodes error -result success
+
+
test namespace-43.1 {ensembles: dict-driven} {
namespace eval ns {
namespace export x*