diff options
Diffstat (limited to 'generic/tclCompile.c')
| -rw-r--r-- | generic/tclCompile.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 87f1bfc..1a7d32f 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -2121,10 +2121,25 @@ TclCompileScript( * has not yet generated any bytecode. */ const char *p = script; /* Where we are in our compile. */ int depth = TclGetStackDepth(envPtr); + Interp *iPtr = (Interp *) interp; if (envPtr->iPtr == NULL) { Tcl_Panic("TclCompileScript() called on uninitialized CompileEnv"); } + /* + * Check depth to avoid SO by too many nested calls of TclCompileScript + * (considering interp recursionlimit). + * Factor 5/4 (1.25) is used to avoid too mistaken limit recognition + * during "mixed" evaluation and compilation process (nested eval+compile) + * and is good enough for default recursionlimit (1000). + */ + if (iPtr->numLevels / 5 > iPtr->maxNestingDepth / 4) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "too many nested compilations (infinite loop?)", -1)); + Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL); + TclCompileSyntaxError(interp, envPtr); + return; + } /* Each iteration compiles one command from the script. */ @@ -2203,8 +2218,16 @@ TclCompileScript( continue; } + /* + * Avoid stack exhaustion by too many nested calls of TclCompileScript + * (considering interp recursionlimit). + */ + iPtr->numLevels++; + lastCmdIdx = CompileCommandTokens(interp, parsePtr, envPtr); + iPtr->numLevels--; + /* * TIP #280: Track lines in the just compiled command. */ |
