diff options
author | stanton <stanton> | 1998-10-06 00:35:42 (GMT) |
---|---|---|
committer | stanton <stanton> | 1998-10-06 00:35:42 (GMT) |
commit | 11eb151d297fbf390077a1e103954120b342e336 (patch) | |
tree | 376770ff9b4caba08b604d64c168eb489a94ce60 | |
parent | cb8a44f6d61fc258cd773d16c4ee84c2a08ab7e1 (diff) | |
download | tcl-11eb151d297fbf390077a1e103954120b342e336.zip tcl-11eb151d297fbf390077a1e103954120b342e336.tar.gz tcl-11eb151d297fbf390077a1e103954120b342e336.tar.bz2 |
* tclCompile.c (TclCompileScript): changed to avoid modifying the
input string in place because name lookup operations could have
arbitrary side effects
-rw-r--r-- | generic/tclCompile.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 7288f86..46ac1d5 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclCompile.c,v 1.1.2.3 1998/09/30 20:46:23 stanton Exp $ + * RCS: @(#) $Id: tclCompile.c,v 1.1.2.4 1998/10/06 00:35:42 stanton Exp $ */ #include "tclInt.h" @@ -694,13 +694,16 @@ TclCompileScript(interp, script, numBytes, nested, envPtr) int startCodeOffset = -1; /* Offset of first byte of current command's * code. Init. to avoid compiler warning. */ unsigned char *entryCodeNext = envPtr->codeNext; - char *word, *p, *next; + char *p, *next; Namespace *cmdNsPtr; Command *cmdPtr; Tcl_Token *tokenPtr; int bytesLeft, isFirstCmd, gotParse, wordIdx, currCmdIndex; int commandLength, objIndex, code; - char savedChar, prev; + char prev; + Tcl_DString ds; + + Tcl_DStringInit(&ds); if (numBytes < 0) { numBytes = strlen(script); @@ -794,21 +797,32 @@ TclCompileScript(interp, script, numBytes, nested, envPtr) * compile procedure, let it compile the command. */ - word = tokenPtr[1].start; - savedChar = word[tokenPtr[1].size]; - word[tokenPtr[1].size] = '\0'; if (wordIdx == 0) { if (envPtr->procPtr != NULL) { cmdNsPtr = envPtr->procPtr->cmdPtr->nsPtr; } else { cmdNsPtr = NULL; /* use current NS */ } - cmdPtr = (Command *) Tcl_FindCommand(interp, word, + + /* + * We copy the string before trying to find the command + * by name. We used to modify the string in place, but + * this is not safe because the name resolution + * handlers could have side effects that rely on the + * unmodified string. + */ + + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, tokenPtr[1].start, + tokenPtr[1].size); + + cmdPtr = (Command *) Tcl_FindCommand(interp, + Tcl_DStringValue(&ds), (Tcl_Namespace *) cmdNsPtr, /*flags*/ 0); + if ((cmdPtr != NULL) && (cmdPtr->compileProc != NULL) && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) { - word[tokenPtr[1].size] = savedChar; code = (*(cmdPtr->compileProc))(interp, &parse, envPtr); if (code == TCL_OK) { @@ -828,19 +842,20 @@ TclCompileScript(interp, script, numBytes, nested, envPtr) * reduce runtime lookups. */ - objIndex = TclRegisterLiteral(envPtr, word, - tokenPtr[1].size, /*onHeap*/ 0); + objIndex = TclRegisterLiteral(envPtr, + tokenPtr[1].start, tokenPtr[1].size, + /*onHeap*/ 0); if (cmdPtr != NULL) { TclSetCmdNameObj(interp, envPtr->literalArrayPtr[objIndex].objPtr, cmdPtr); } } else { - objIndex = TclRegisterLiteral(envPtr, word, - tokenPtr[1].size, /*onHeap*/ 0); + objIndex = TclRegisterLiteral(envPtr, + tokenPtr[1].start, tokenPtr[1].size, + /*onHeap*/ 0); } TclEmitPush(objIndex, envPtr); - word[tokenPtr[1].size] = savedChar; maxDepth = TclMax((wordIdx + 1), maxDepth); } else { /* @@ -918,6 +933,7 @@ TclCompileScript(interp, script, numBytes, nested, envPtr) iPtr->termOffset = (p - script); } envPtr->maxStackDepth = maxDepth; + Tcl_DStringFree(&ds); return TCL_OK; error: @@ -950,6 +966,7 @@ TclCompileScript(interp, script, numBytes, nested, envPtr) } iPtr->termOffset = (p - script); envPtr->maxStackDepth = maxDepth; + Tcl_DStringFree(&ds); return code; } @@ -2923,6 +2940,7 @@ TclPrintByteCodeObj(interp, objPtr) unsigned char *codeDeltaNext, *codeLengthNext; unsigned char *srcDeltaNext, *srcLengthNext; int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i; + Interp *iPtr = (Interp *) *codePtr->interpHandle; if (codePtr->refCount <= 0) { return; /* already freed */ @@ -2938,8 +2956,8 @@ TclPrintByteCodeObj(interp, objPtr) fprintf(stdout, "\nByteCode 0x%x, refCt %u, epoch %u, interp 0x%x (epoch %u)\n", (unsigned int) codePtr, codePtr->refCount, - codePtr->compileEpoch, (unsigned int) codePtr->iPtr, - codePtr->iPtr->compileEpoch); + codePtr->compileEpoch, (unsigned int) iPtr, + iPtr->compileEpoch); fprintf(stdout, " Source "); TclPrintSource(stdout, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); @@ -3408,7 +3426,8 @@ RecordByteCodeStats(codePtr) ByteCode *codePtr; /* Points to ByteCode structure with info * to add to accumulated statistics. */ { - register ByteCodeStats *statsPtr = &(codePtr->iPtr->stats); + Interp *iPtr = (Interp *) *codePtr->interpHandle; + register ByteCodeStats *statsPtr = &(iPtr->stats); statsPtr->numCompilations++; statsPtr->totalSrcBytes += (double) codePtr->numSrcBytes; |