aboutsummaryrefslogtreecommitdiff
path: root/jim.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2020-12-20 07:58:30 +1000
committerSteve Bennett <steveb@workware.net.au>2020-12-26 18:08:29 +1000
commit3627155c4a047bc491d45406b22a9038402ae964 (patch)
tree7f0337e433cdec49841d218dce420f4f274622b8 /jim.c
parentea1b12824f360ca2f3b4838e1d88605b9b1c1a6d (diff)
downloadjimtcl-3627155c4a047bc491d45406b22a9038402ae964.zip
jimtcl-3627155c4a047bc491d45406b22a9038402ae964.tar.gz
jimtcl-3627155c4a047bc491d45406b22a9038402ae964.tar.bz2
Jim_GetWideExpr() now evaluates "safe" expressions
This means that $variable references and [commands] are not expanded. This should mitigate security concerns when using the 'integer expression' feature. It means that you must do: string repeat a $i*4 Not: string repeat a {$i*4} Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim.c')
-rw-r--r--jim.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/jim.c b/jim.c
index 75a6a1d..4124a4d 100644
--- a/jim.c
+++ b/jim.c
@@ -4729,6 +4729,9 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr,
*/
Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
{
+ if (interp->safeexpr) {
+ return nameObjPtr;
+ }
switch (SetVariableFromAny(interp, nameObjPtr)) {
case JIM_OK:{
Jim_Var *varPtr = nameObjPtr->internalRep.varValue.varPtr;
@@ -5020,6 +5023,10 @@ static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_Obj *resObjPtr = NULL;
Jim_Obj *substKeyObjPtr = NULL;
+ if (interp->safeexpr) {
+ return objPtr;
+ }
+
SetDictSubstFromAny(interp, objPtr);
if (Jim_SubstObj(interp, objPtr->internalRep.dictSubstValue.indexObjPtr,
@@ -6070,7 +6077,14 @@ int Jim_GetWideExpr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr)
*widePtr = JimWideValue(objPtr);
}
else {
+ /* safeexpr can never be set here, because evaluating an expression
+ * safely can never cause a script to be run
+ */
+ JimPanic((interp->safeexpr, "interp->safeexpr is set"));
+ interp->safeexpr++;
ret = Jim_EvalExpression(interp, objPtr);
+ interp->safeexpr--;
+
if (ret == JIM_OK) {
ret = Jim_GetWide(interp, Jim_GetResult(interp), widePtr);
}
@@ -9190,8 +9204,7 @@ static void JimShowExprNode(struct JimExprNode *node, int level)
*
* 'exp_numterms' indicates how many terms are expected. Normally this is 1, but may be more for EXPR_FUNC_ARGS and EXPR_TERNARY.
*/
-static int ExprTreeBuildTree(Jim_Interp *interp, struct ExprBuilder *builder, int precedence, int flags, int exp_numterms)
-{
+static int ExprTreeBuildTree(Jim_Interp *interp, struct ExprBuilder *builder, int precedence, int flags, int exp_numterms) {
int rc;
struct JimExprNode *node;
/* Calculate the stack length expected after pushing the number of expected terms */
@@ -9643,6 +9656,9 @@ static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node)
return JIM_ERR;
case JIM_TT_ESC:
+ if (interp->safeexpr) {
+ return JIM_ERR;
+ }
if (Jim_SubstObj(interp, node->objPtr, &objPtr, JIM_NONE) == JIM_OK) {
Jim_SetResult(interp, objPtr);
return JIM_OK;
@@ -9650,6 +9666,9 @@ static int JimExprEvalTermNode(Jim_Interp *interp, struct JimExprNode *node)
return JIM_ERR;
case JIM_TT_CMD:
+ if (interp->safeexpr) {
+ return JIM_ERR;
+ }
return Jim_EvalObj(interp, node->objPtr);
default:
@@ -9702,7 +9721,7 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr)
* $a != CONST, $a != $b
* $a == CONST, $a == $b
*/
- {
+ if (!interp->safeexpr) {
Jim_Obj *objPtr;
/* STEP 1 -- Check if there are the conditions to run the specialized