aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--jim.c11
-rw-r--r--jim.h2
3 files changed, 18 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 0707a1a..619ce60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2008-11-06 Steve Bennett <steveb@workware.net.au>
+ * jim.c, jim.h: Prevent infinite recursion if an unknown command is
+ called from unknown
+
+2008-11-06 Steve Bennett <steveb@workware.net.au>
+
* jim-array-1.0.tcl: Add array command wrapper
2008-11-05 Steve Bennett <steveb@workware.net.au>
diff --git a/jim.c b/jim.c
index eea9bd3..b859939 100644
--- a/jim.c
+++ b/jim.c
@@ -4436,6 +4436,7 @@ Jim_Interp *Jim_CreateInterp(void)
i->result = i->emptyObj;
i->stackTrace = Jim_NewListObj(i, NULL, 0);
i->unknown = Jim_NewStringObj(i, "unknown", -1);
+ i->unknown_called = 0;
Jim_IncrRefCount(i->emptyObj);
Jim_IncrRefCount(i->result);
Jim_IncrRefCount(i->stackTrace);
@@ -8325,6 +8326,13 @@ static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Jim_Obj **v, *sv[JIM_EVAL_SARGV_LEN];
int retCode;
+ /* If JimUnknown() is recursively called (e.g. error in the unknown proc,
+ * done here
+ */
+ if (interp->unknown_called) {
+ return JIM_ERR;
+ }
+
/* If the [unknown] command does not exists returns
* just now */
if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
@@ -8345,7 +8353,10 @@ static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
memcpy(v+1, argv, sizeof(Jim_Obj*)*argc);
v[0] = interp->unknown;
/* Call it */
+ interp->unknown_called++;
retCode = Jim_EvalObjVector(interp, argc+1, v);
+ interp->unknown_called--;
+
/* Clean up */
if (v != sv)
Jim_Free(v);
diff --git a/jim.h b/jim.h
index a48d04c..490b65b 100644
--- a/jim.h
+++ b/jim.h
@@ -530,6 +530,7 @@ typedef struct Jim_Interp {
struct Jim_HashTable sharedStrings; /* Shared Strings hash table */
Jim_Obj *stackTrace; /* Stack trace object. */
Jim_Obj *unknown; /* Unknown command cache */
+ int unknown_called; /* The unknown command has been invoked */
int errorFlag; /* Set if an error occurred during execution. */
int evalRetcodeLevel; /* Level where the last return with code JIM_EVAL
happened. */
@@ -560,6 +561,7 @@ typedef struct Jim_Interp {
* cached can no longer considered valid. */
#define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
#define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
+#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
#define Jim_SetEmptyResult(i) Jim_SetResult(i, (i)->emptyObj)
#define Jim_GetResult(i) ((i)->result)
#define Jim_CmdPrivData(i) ((i)->cmdPrivData)