From 81cbdd313896511542f19465bf012631591474db Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Oct 2015 13:14:27 +0000 Subject: Where "interp" is only used for error-reporting, it can be allowed to be NULL. This should fix [5da26d4760]: Tcl_LoadFile() segfaults if "interp" is NULL. --- generic/tclIOUtil.c | 34 +++++++++++++++++++--------- generic/tclLoadNone.c | 14 +++++++----- unix/tclLoadDl.c | 25 ++++++++++++--------- win/tclWinLoad.c | 62 ++++++++++++++++++++++++++------------------------- 4 files changed, 79 insertions(+), 56 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 1d4f277..1330c02 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -3254,7 +3254,9 @@ Tcl_LoadFile( if (*handlePtr == NULL) { return TCL_ERROR; } - Tcl_ResetResult(interp); + if (interp) { + Tcl_ResetResult(interp); + } goto resolveSymbols; } if (Tcl_GetErrno() != EXDEV) { @@ -3270,9 +3272,11 @@ Tcl_LoadFile( */ if (Tcl_FSAccess(pathPtr, R_OK) != 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't load library \"%s\": %s", - Tcl_GetString(pathPtr), Tcl_PosixError(interp))); + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't load library \"%s\": %s", + Tcl_GetString(pathPtr), Tcl_PosixError(interp))); + } return TCL_ERROR; } @@ -3321,7 +3325,9 @@ Tcl_LoadFile( } mustCopyToTempAnyway: - Tcl_ResetResult(interp); + if (interp) { + Tcl_ResetResult(interp); + } #endif /* TCL_LOAD_FROM_MEMORY */ /* @@ -3345,8 +3351,10 @@ Tcl_LoadFile( Tcl_FSDeleteFile(copyToPtr); Tcl_DecrRefCount(copyToPtr); - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "couldn't load from current filesystem", -1)); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "couldn't load from current filesystem", -1)); + } return TCL_ERROR; } @@ -3386,7 +3394,9 @@ Tcl_LoadFile( * have stored the number of bytes in the result. */ - Tcl_ResetResult(interp); + if (interp) { + Tcl_ResetResult(interp); + } retVal = Tcl_LoadFile(interp, copyToPtr, symbols, flags, procPtrs, &newLoadHandle); @@ -3418,7 +3428,9 @@ Tcl_LoadFile( */ *handlePtr = newLoadHandle; - Tcl_ResetResult(interp); + if (interp) { + Tcl_ResetResult(interp); + } return TCL_OK; } @@ -3479,7 +3491,9 @@ Tcl_LoadFile( divertedLoadHandle->unloadFileProcPtr = DivertUnloadFile; *handlePtr = divertedLoadHandle; - Tcl_ResetResult(interp); + if (interp) { + Tcl_ResetResult(interp); + } return retVal; resolveSymbols: diff --git a/generic/tclLoadNone.c b/generic/tclLoadNone.c index 6cb4378..6af5c4f 100644 --- a/generic/tclLoadNone.c +++ b/generic/tclLoadNone.c @@ -45,9 +45,11 @@ TclpDlopen( * file. */ int flags) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "dynamic loading is not currently available on this system", - -1)); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "dynamic loading is not currently available on this system", + -1)); + } return TCL_ERROR; } @@ -109,8 +111,10 @@ TclpLoadMemory( int flags) /* Dummy: unused by this implementation */ { - Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory " - "is not available on this system", -1)); + if (interp) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory " + "is not available on this system", -1)); + } return TCL_ERROR; } diff --git a/unix/tclLoadDl.c b/unix/tclLoadDl.c index dc711f8..aec071c 100644 --- a/unix/tclLoadDl.c +++ b/unix/tclLoadDl.c @@ -124,9 +124,11 @@ TclpDlopen( const char *errorStr = dlerror(); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't load file \"%s\": %s", - Tcl_GetString(pathPtr), errorStr)); + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't load file \"%s\": %s", + Tcl_GetString(pathPtr), errorStr)); + } return TCL_ERROR; } newHandle = ckalloc(sizeof(*newHandle)); @@ -187,17 +189,18 @@ FindSymbol( Tcl_DStringFree(&newName); } Tcl_DStringFree(&ds); - if (proc == NULL && interp != NULL) { + if (proc == NULL) { const char *errorStr = dlerror(); - if (!errorStr) { - errorStr = "unknown"; + if (interp) { + if (!errorStr) { + errorStr = "unknown"; + } + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "cannot find symbol \"%s\": %s", symbol, errorStr)); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, + NULL); } - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "cannot find symbol \"%s\": %s", symbol, errorStr)); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, - NULL); } return proc; } diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c index 3e11224..26512b1 100644 --- a/win/tclWinLoad.c +++ b/win/tclWinLoad.c @@ -102,37 +102,39 @@ TclpDlopen( * better if there was a way to get what DLLs */ - switch (lastError) { - case ERROR_MOD_NOT_FOUND: - Tcl_SetErrorCode(interp, "WIN_LOAD", "MOD_NOT_FOUND", NULL); - goto notFoundMsg; - case ERROR_DLL_NOT_FOUND: - Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_NOT_FOUND", NULL); - notFoundMsg: - Tcl_AppendToObj(errMsg, "this library or a dependent library" - " could not be found in library path", -1); - break; - case ERROR_PROC_NOT_FOUND: - Tcl_SetErrorCode(interp, "WIN_LOAD", "PROC_NOT_FOUND", NULL); - Tcl_AppendToObj(errMsg, "A function specified in the import" - " table could not be resolved by the system. Windows" - " is not telling which one, I'm sorry.", -1); - break; - case ERROR_INVALID_DLL: - Tcl_SetErrorCode(interp, "WIN_LOAD", "INVALID_DLL", NULL); - Tcl_AppendToObj(errMsg, "this library or a dependent library" - " is damaged", -1); - break; - case ERROR_DLL_INIT_FAILED: - Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_INIT_FAILED", NULL); - Tcl_AppendToObj(errMsg, "the library initialization" - " routine failed", -1); - break; - default: - TclWinConvertError(lastError); - Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), -1); + if (interp) { + switch (lastError) { + case ERROR_MOD_NOT_FOUND: + Tcl_SetErrorCode(interp, "WIN_LOAD", "MOD_NOT_FOUND", NULL); + goto notFoundMsg; + case ERROR_DLL_NOT_FOUND: + Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_NOT_FOUND", NULL); + notFoundMsg: + Tcl_AppendToObj(errMsg, "this library or a dependent library" + " could not be found in library path", -1); + break; + case ERROR_PROC_NOT_FOUND: + Tcl_SetErrorCode(interp, "WIN_LOAD", "PROC_NOT_FOUND", NULL); + Tcl_AppendToObj(errMsg, "A function specified in the import" + " table could not be resolved by the system. Windows" + " is not telling which one, I'm sorry.", -1); + break; + case ERROR_INVALID_DLL: + Tcl_SetErrorCode(interp, "WIN_LOAD", "INVALID_DLL", NULL); + Tcl_AppendToObj(errMsg, "this library or a dependent library" + " is damaged", -1); + break; + case ERROR_DLL_INIT_FAILED: + Tcl_SetErrorCode(interp, "WIN_LOAD", "DLL_INIT_FAILED", NULL); + Tcl_AppendToObj(errMsg, "the library initialization" + " routine failed", -1); + break; + default: + TclWinConvertError(lastError); + Tcl_AppendToObj(errMsg, Tcl_PosixError(interp), -1); + } + Tcl_SetObjResult(interp, errMsg); } - Tcl_SetObjResult(interp, errMsg); return TCL_ERROR; } -- cgit v0.12