diff options
author | dgp <dgp@users.sourceforge.net> | 2019-03-08 14:46:26 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2019-03-08 14:46:26 (GMT) |
commit | df5dff900864760f02f1b93de275b401a5505f0e (patch) | |
tree | 8a25decae54c49bf39a7c7a266ebc4dfc2b24dc3 /generic/tclPkg.c | |
parent | 2680fee6ce5b83af58184dcdb82ec765d431bbb1 (diff) | |
parent | c5abbcaaf4c32c6bfce25ff1a589f6e704116729 (diff) | |
download | tcl-df5dff900864760f02f1b93de275b401a5505f0e.zip tcl-df5dff900864760f02f1b93de275b401a5505f0e.tar.gz tcl-df5dff900864760f02f1b93de275b401a5505f0e.tar.bz2 |
[39fed4dae5] Make sure return value from Tcl_PkgRequire*() survives long enough
for caller to use it.
Diffstat (limited to 'generic/tclPkg.c')
-rw-r--r-- | generic/tclPkg.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/generic/tclPkg.c b/generic/tclPkg.c index d4080c2..c1e2078 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -40,10 +40,7 @@ typedef struct PkgAvail { */ typedef struct Package { - char *version; /* Version that has been supplied in this - * interpreter via "package provide" - * (malloc'ed). NULL means the package doesn't - * exist in this interpreter yet. */ + Tcl_Obj *version; PkgAvail *availPtr; /* First in list of all available versions of * this package. */ const void *clientData; /* Client data. */ @@ -150,12 +147,13 @@ Tcl_PkgProvideEx( pkgPtr = FindPackage(interp, name); if (pkgPtr->version == NULL) { - DupString(pkgPtr->version, version); + pkgPtr->version = Tcl_NewStringObj(version, -1); + Tcl_IncrRefCount(pkgPtr->version); pkgPtr->clientData = clientData; return TCL_OK; } - if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi, + if (CheckVersionAndConvert(interp, Tcl_GetString(pkgPtr->version), &pvi, NULL) != TCL_OK) { return TCL_ERROR; } else if (CheckVersionAndConvert(interp, version, &vi, NULL) != TCL_OK) { @@ -175,7 +173,7 @@ Tcl_PkgProvideEx( } Tcl_SetObjResult(interp, Tcl_ObjPrintf( "conflicting versions provided for package \"%s\": %s, then %s", - name, pkgPtr->version, version)); + name, Tcl_GetString(pkgPtr->version), version)); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT", NULL); return TCL_ERROR; } @@ -318,7 +316,7 @@ Tcl_PkgRequireEx( if (version == NULL) { if (Tcl_PkgRequireProc(interp, name, 0, NULL, clientDataPtr) == TCL_OK) { - result = Tcl_GetStringResult(interp); + result = Tcl_GetString(Tcl_GetObjResult(interp)); Tcl_ResetResult(interp); } } else { @@ -332,7 +330,7 @@ Tcl_PkgRequireEx( } Tcl_IncrRefCount(ov); if (Tcl_PkgRequireProc(interp, name, 1, &ov, clientDataPtr) == TCL_OK) { - result = Tcl_GetStringResult(interp); + result = Tcl_GetString(Tcl_GetObjResult(interp)); Tcl_ResetResult(interp); } TclDecrRefCount(ov); @@ -474,7 +472,8 @@ PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result) { */ if (reqc != 0) { - CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pkgVersionI, NULL); + CheckVersionAndConvert(interp, Tcl_GetString(reqPtr->pkgPtr->version), + &pkgVersionI, NULL); satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv); ckfree(pkgVersionI); @@ -482,7 +481,7 @@ PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result) { if (!satisfies) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "version conflict for package \"%s\": have %s, need", - name, reqPtr->pkgPtr->version)); + name, Tcl_GetString(reqPtr->pkgPtr->version))); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT", NULL); AddRequirementsToResult(interp, reqc, reqv); @@ -495,7 +494,7 @@ PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result) { *ptr = reqPtr->pkgPtr->clientData; } - Tcl_SetObjResult(interp, Tcl_NewStringObj(reqPtr->pkgPtr->version, -1)); + Tcl_SetObjResult(interp, reqPtr->pkgPtr->version); return TCL_OK; } @@ -694,8 +693,8 @@ SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) { } else { char *pvi, *vi; - if (CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pvi, - NULL) != TCL_OK) { + if (TCL_OK != CheckVersionAndConvert(interp, + Tcl_GetString(reqPtr->pkgPtr->version), &pvi, NULL)) { result = TCL_ERROR; } else if (CheckVersionAndConvert(interp, versionToProvide, &vi, NULL) != TCL_OK) { @@ -712,7 +711,7 @@ SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) { "attempt to provide package %s %s failed:" " package %s %s provided instead", name, versionToProvide, - name, reqPtr->pkgPtr->version)); + name, Tcl_GetString(reqPtr->pkgPtr->version))); Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "WRONGPROVIDE", NULL); } @@ -750,7 +749,7 @@ SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) { */ if (reqPtr->pkgPtr->version != NULL) { - ckfree(reqPtr->pkgPtr->version); + Tcl_DecrRefCount(reqPtr->pkgPtr->version); reqPtr->pkgPtr->version = NULL; } reqPtr->pkgPtr->clientData = NULL; @@ -926,7 +925,7 @@ TclNRPackageObjCmd( pkgPtr = Tcl_GetHashValue(hPtr); Tcl_DeleteHashEntry(hPtr); if (pkgPtr->version != NULL) { - ckfree(pkgPtr->version); + Tcl_DecrRefCount(pkgPtr->version); } while (pkgPtr->availPtr != NULL) { availPtr = pkgPtr->availPtr; @@ -1084,8 +1083,7 @@ TclNRPackageObjCmd( if (hPtr != NULL) { pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(pkgPtr->version, -1)); + Tcl_SetObjResult(interp, pkgPtr->version); } } return TCL_OK; @@ -1378,7 +1376,7 @@ TclFreePackageInfo( hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { - ckfree(pkgPtr->version); + Tcl_DecrRefCount(pkgPtr->version); } while (pkgPtr->availPtr != NULL) { availPtr = pkgPtr->availPtr; |