From e76d16d3eba7f034fc003f1061736c298b03c74f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 7 Dec 2012 21:28:49 +0000 Subject: only set tclStubsPtr if all version checks pass. Backported from tcl 8.5. --- generic/tclStubLib.c | 105 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/generic/tclStubLib.c b/generic/tclStubLib.c index 7bf04a0..39e94c8 100644 --- a/generic/tclStubLib.c +++ b/generic/tclStubLib.c @@ -1,45 +1,26 @@ -/* +/* * tclStubLib.c -- * - * Stub object that will be statically linked into extensions that wish + * Stub object that will be statically linked into extensions that want * to access Tcl. * * Copyright (c) 1998-1999 by Scriptics Corporation. * Copyright (c) 1998 Paul Duffin. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -/* - * We need to ensure that we use the stub macros so that this file contains - * no references to any of the stub functions. This will make it possible - * to build an extension that references Tcl_InitStubs but doesn't end up - * including the rest of the stub functions. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#ifndef USE_TCL_STUBS -#define USE_TCL_STUBS -#endif -#undef USE_TCL_STUB_PROCS - #include "tclInt.h" #include "tclPort.h" -/* - * Ensure that Tcl_InitStubs is built as an exported symbol. The other stub - * functions should be built as non-exported symbols. - */ - TclStubs *tclStubsPtr = NULL; TclPlatStubs *tclPlatStubsPtr = NULL; TclIntStubs *tclIntStubsPtr = NULL; TclIntPlatStubs *tclIntPlatStubsPtr = NULL; -static TclStubs * HasStubSupport _ANSI_ARGS_((Tcl_Interp *interp)); - static TclStubs * -HasStubSupport (interp) +HasStubSupport(interp) Tcl_Interp *interp; { Interp *iPtr = (Interp *) interp; @@ -49,57 +30,87 @@ HasStubSupport (interp) } interp->result = "interpreter uses an incompatible stubs mechanism"; interp->freeProc = TCL_STATIC; - return NULL; } /* + * Use our own isdigit to avoid linking to libc on windows + */ + +static int isDigit(const int c) +{ + return (c >= '0' && c <= '9'); +} + +/* *---------------------------------------------------------------------- * * Tcl_InitStubs -- * - * Tries to initialise the stub table pointers and ensures that - * the correct version of Tcl is loaded. + * Tries to initialise the stub table pointers and ensures that the + * correct version of Tcl is loaded. * * Results: - * The actual version of Tcl that satisfies the request, or - * NULL to indicate that an error occurred. + * The actual version of Tcl that satisfies the request, or NULL to + * indicate that an error occurred. * * Side effects: * Sets the stub table pointers. * *---------------------------------------------------------------------- */ - -#ifdef Tcl_InitStubs #undef Tcl_InitStubs -#endif - CONST char * -Tcl_InitStubs (interp, version, exact) +Tcl_InitStubs(interp, version, exact) Tcl_Interp *interp; CONST char *version; int exact; { CONST char *actualVersion = NULL; - ClientData pkgData = NULL; + TclStubs *stubsPtr; /* - * We can't optimize this check by caching tclStubsPtr because - * that prevents apps from being able to load/unload Tcl dynamically - * multiple times. [Bug 615304] + * We can't optimize this check by caching tclStubsPtr because that + * prevents apps from being able to load/unload Tcl dynamically multiple + * times. [Bug 615304] */ - tclStubsPtr = HasStubSupport(interp); - if (!tclStubsPtr) { + stubsPtr = HasStubSupport(interp); + if (!stubsPtr) { return NULL; } - actualVersion = Tcl_PkgRequireEx(interp, "Tcl", version, exact, &pkgData); + actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, NULL); if (actualVersion == NULL) { return NULL; } - tclStubsPtr = (TclStubs*)pkgData; + if (exact) { + CONST char *p = version; + int count = 0; + + while (*p) { + count += !isDigit(*p++); + } + if (count == 1) { + CONST char *q = actualVersion; + + p = version; + while (*p && (*p == *q)) { + p++; q++; + } + if (*p || isDigit(*q)) { + /* Construct error message */ + stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); + return NULL; + } + } else { + actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); + if (actualVersion == NULL) { + return NULL; + } + } + } + tclStubsPtr = stubsPtr; if (tclStubsPtr->hooks) { tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs; @@ -110,6 +121,14 @@ Tcl_InitStubs (interp, version, exact) tclIntStubsPtr = NULL; tclIntPlatStubsPtr = NULL; } - + return actualVersion; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ -- cgit v0.12