Tcl Source Code

Check-in [fa161ec8b8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More symmetric Tcl_(Incr|Decr)RefCount call, preventing bugs like #3601260 and #3602706
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fa161ec8b8d28f24317f8eec545677a668b991f7
User & Date: jan.nijtmans 2013-02-03 11:34:01
Context
2013-02-04
10:51
Eliminate all Tcl_ConvertToType calls and all direct calls to typePtr->setFromAnyProc (except the ca... check-in: af25d8dc8c user: jan.nijtmans tags: trunk
2013-02-03
16:07
merge trunk check-in: 4c05d0f9d9 user: jan.nijtmans tags: initsubsystems
16:05
merge trunk check-in: 127b30eda5 user: jan.nijtmans tags: novem
11:34
More symmetric Tcl_(Incr|Decr)RefCount call, preventing bugs like #3601260 and #3602706 check-in: fa161ec8b8 user: jan.nijtmans tags: trunk
11:31
re-apply [8aca9a8e96], while backporting [d91c86d0da] from trunk. This fixes bugs #3601260 and #3602... check-in: 8e90418421 user: jan.nijtmans tags: core-8-5-branch
2013-01-31
13:50
Bug [3598282]: Stop using installData.tcl to install the timezone files. check-in: 70995bd619 user: stwo tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclVar.c.

471
472
473
474
475
476
477

478
479
480
481
482
483
484
				 * is set to NULL. */
{
    Tcl_Obj *part2Ptr = NULL;
    Var *resPtr;

    if (part2) {
	part2Ptr = Tcl_NewStringObj(part2, -1);

    }

    resPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
	    flags, msg, createPart1, createPart2, arrayPtrPtr);

    if (part2Ptr) {
	Tcl_DecrRefCount(part2Ptr);







>







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
				 * is set to NULL. */
{
    Tcl_Obj *part2Ptr = NULL;
    Var *resPtr;

    if (part2) {
	part2Ptr = Tcl_NewStringObj(part2, -1);
	Tcl_IncrRefCount(part2Ptr);
    }

    resPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
	    flags, msg, createPart1, createPart2, arrayPtrPtr);

    if (part2Ptr) {
	Tcl_DecrRefCount(part2Ptr);
1320
1321
1322
1323
1324
1325
1326

1327
1328

1329
1330
1331
1332
1333
1334
1335
    const char *part2,		/* If non-NULL, gives the name of an element
				 * in the array part1. */
    int flags)			/* OR-ed combination of TCL_GLOBAL_ONLY, and
				 * TCL_LEAVE_ERR_MSG bits. */
{
    Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);


    if (part2) {
	part2Ptr = Tcl_NewStringObj(part2, -1);

    }

    resPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);

    Tcl_DecrRefCount(part1Ptr);
    if (part2Ptr) {
	Tcl_DecrRefCount(part2Ptr);







>


>







1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
    const char *part2,		/* If non-NULL, gives the name of an element
				 * in the array part1. */
    int flags)			/* OR-ed combination of TCL_GLOBAL_ONLY, and
				 * TCL_LEAVE_ERR_MSG bits. */
{
    Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);

    Tcl_IncrRefCount(part1Ptr);
    if (part2) {
	part2Ptr = Tcl_NewStringObj(part2, -1);
	Tcl_IncrRefCount(part2Ptr);
    }

    resPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);

    Tcl_DecrRefCount(part1Ptr);
    if (part2Ptr) {
	Tcl_DecrRefCount(part2Ptr);
2214
2215
2216
2217
2218
2219
2220

2221
2222

2223
2224
2225
2226
2227
2228
2229
    int flags)			/* OR-ed combination of any of
				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
				 * TCL_LEAVE_ERR_MSG. */
{
    int result;
    Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);


    if (part2) {
	part2Ptr = Tcl_NewStringObj(part2, -1);

    }

    /*
     * Filter to pass through only the flags this interface supports.
     */

    flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);







>


>







2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
    int flags)			/* OR-ed combination of any of
				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
				 * TCL_LEAVE_ERR_MSG. */
{
    int result;
    Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);

    Tcl_IncrRefCount(part1Ptr);
    if (part2) {
	part2Ptr = Tcl_NewStringObj(part2, -1);
	Tcl_IncrRefCount(part2Ptr);
    }

    /*
     * Filter to pass through only the flags this interface supports.
     */

    flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
    searchPtr->nextEntry = VarHashFirstEntry(varPtr->value.tablePtr,
	    &searchPtr->search);
    Tcl_SetHashValue(hPtr, searchPtr);
    Tcl_SetObjResult(interp,
	    Tcl_ObjPrintf("s-%d-%s", searchPtr->id, varName));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ArrayAnyMoreCmd --
 *
 *	This object-based function is invoked to process the "array anymore"
 *	Tcl command. See the user documentation for details on what it does.







|







3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
    searchPtr->nextEntry = VarHashFirstEntry(varPtr->value.tablePtr,
	    &searchPtr->search);
    Tcl_SetHashValue(hPtr, searchPtr);
    Tcl_SetObjResult(interp,
	    Tcl_ObjPrintf("s-%d-%s", searchPtr->id, varName));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ArrayAnyMoreCmd --
 *
 *	This object-based function is invoked to process the "array anymore"
 *	Tcl command. See the user documentation for details on what it does.
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
	    gotValue = 0;
	    break;
	}
    }
    Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[gotValue]);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ArrayNextElementCmd --
 *
 *	This object-based function is invoked to process the "array
 *	nextelement" Tcl command. See the user documentation for details on







|







3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
	    gotValue = 0;
	    break;
	}
    }
    Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[gotValue]);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ArrayNextElementCmd --
 *
 *	This object-based function is invoked to process the "array
 *	nextelement" Tcl command. See the user documentation for details on
5774
5775
5776
5777
5778
5779
5780

5781
5782
5783
5784
5785
5786
5787
				 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
				 * and TCL_NAMESPACE_ONLY are given,
				 * TCL_GLOBAL_ONLY is ignored. */
{
    Tcl_Obj *namePtr = Tcl_NewStringObj(name, -1);
    Tcl_Var var;


    var = ObjFindNamespaceVar(interp, namePtr, contextNsPtr, flags);
    Tcl_DecrRefCount(namePtr);
    return var;
}

static Tcl_Var
ObjFindNamespaceVar(







>







5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
				 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
				 * and TCL_NAMESPACE_ONLY are given,
				 * TCL_GLOBAL_ONLY is ignored. */
{
    Tcl_Obj *namePtr = Tcl_NewStringObj(name, -1);
    Tcl_Var var;

    Tcl_IncrRefCount(namePtr);
    var = ObjFindNamespaceVar(interp, namePtr, contextNsPtr, flags);
    Tcl_DecrRefCount(namePtr);
    return var;
}

static Tcl_Var
ObjFindNamespaceVar(
5868
5869
5870
5871
5872
5873
5874

5875
5876
5877
5878
5879
5880
5881
     * to check both possible search paths: from the specified namespace
     * context and from the global namespace.
     */

    varPtr = NULL;
    if (simpleName != name) {
	simpleNamePtr = Tcl_NewStringObj(simpleName, -1);

    } else {
	simpleNamePtr = namePtr;
    }

    for (search = 0;  (search < 2) && (varPtr == NULL);  search++) {
	if ((nsPtr[search] != NULL) && (simpleName != NULL)) {
	    varPtr = VarHashFindVar(&nsPtr[search]->varTable, simpleNamePtr);







>







5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
     * to check both possible search paths: from the specified namespace
     * context and from the global namespace.
     */

    varPtr = NULL;
    if (simpleName != name) {
	simpleNamePtr = Tcl_NewStringObj(simpleName, -1);
	Tcl_IncrRefCount(simpleNamePtr);
    } else {
	simpleNamePtr = namePtr;
    }

    for (search = 0;  (search < 2) && (varPtr == NULL);  search++) {
	if ((nsPtr[search] != NULL) && (simpleName != NULL)) {
	    varPtr = VarHashFindVar(&nsPtr[search]->varTable, simpleNamePtr);