diff options
| author | dkf <donal.k.fellows@manchester.ac.uk> | 2023-11-27 09:48:05 (GMT) |
|---|---|---|
| committer | dkf <donal.k.fellows@manchester.ac.uk> | 2023-11-27 09:48:05 (GMT) |
| commit | a7b3d763333065aa11b920d8f1c2529370c1c693 (patch) | |
| tree | 4826a8b40c68bf1f89429c56f3e29f660da7be9e | |
| parent | 92bf9462f38848b1146711f8391b6547d6b01301 (diff) | |
| download | tcl-a7b3d763333065aa11b920d8f1c2529370c1c693.zip tcl-a7b3d763333065aa11b920d8f1c2529370c1c693.tar.gz tcl-a7b3d763333065aa11b920d8f1c2529370c1c693.tar.bz2 | |
Constants can't be written to or unset
| -rw-r--r-- | generic/tclVar.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/generic/tclVar.c b/generic/tclVar.c index 5bb4db3..e952614 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -128,6 +128,7 @@ static const char BADNAMESPACE[] = "parent namespace doesn't exist"; static const char MISSINGNAME[] = "missing variable name"; static const char ISARRAYELEMENT[] = "name refers to an element in an array"; +static const char ISCONST[] = "variable is a constant"; /* * A test to see if we are in a call frame that has local variables. This is @@ -1942,6 +1943,17 @@ TclPtrSetVarIdx( } /* + * It's an error to try to set a constant. + */ + if (TclIsVarConstant(varPtr)) { + if (flags & TCL_LEAVE_ERR_MSG) { + TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "set", ISCONST,index); + Tcl_SetErrorCode(interp, "TCL", "WRITE", "CONST", (void *)NULL); + } + goto earlyError; + } + + /* * It's an error to try to set an array variable itself. */ @@ -2221,6 +2233,17 @@ TclPtrIncrObjVarIdx( { Tcl_Obj *varValuePtr; + /* + * It's an error to try to increment a constant. + */ + if (TclIsVarConstant(varPtr)) { + if (flags & TCL_LEAVE_ERR_MSG) { + TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "incr", ISCONST,index); + Tcl_SetErrorCode(interp, "TCL", "WRITE", "CONST", (void *)NULL); + } + return NULL; + } + if (TclIsVarInHash(varPtr)) { VarHashRefCount(varPtr)++; } @@ -2429,14 +2452,14 @@ int TclPtrUnsetVarIdx( Tcl_Interp *interp, /* Command interpreter in which varName is to * be looked up. */ - Var *varPtr, /* The variable to be unset. */ + Var *varPtr, /* The variable to be unset. */ Var *arrayPtr, /* NULL for scalar variables, pointer to the * containing array otherwise. */ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or * the name of a variable. */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ - int flags, /* OR-ed combination of any of + int flags, /* OR-ed combination of any of * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY, * TCL_LEAVE_ERR_MSG. */ int index) /* Index into the local variable table of the @@ -2448,6 +2471,17 @@ TclPtrUnsetVarIdx( Var *initialArrayPtr = arrayPtr; /* + * It's an error to try to unset a constant. + */ + if (TclIsVarConstant(varPtr)) { + if (flags & TCL_LEAVE_ERR_MSG) { + TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "unset", ISCONST,index); + Tcl_SetErrorCode(interp, "TCL", "UNSET", "CONST", (void *)NULL); + } + return TCL_ERROR; + } + + /* * Keep the variable alive until we're done with it. We used to * increase/decrease the refCount for each operation, making it hard to * find [Bug 735335] - caused by unsetting the variable whose value was |
