Tcl Source Code

Check-in [0da07d5b1e]
Login

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

Overview
Comment:Make sure SetFooFromAny routines react reasonably when passed a NULL interp.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA1: 0da07d5b1e2189ddb3e03e53da787dc681cb46bc
User & Date: dgp 2011-04-21 13:24:25
Context
2011-04-21
16:53
Limits on list length were too strict. Revised panics to errors where possible. check-in: 9080c06a95 user: dgp tags: core-8-5-branch
13:47
Make sure SetFooFromAny routines react reasonably when passed a NULL interp. check-in: 36b0307ba2 user: dgp tags: trunk
13:24
Make sure SetFooFromAny routines react reasonably when passed a NULL interp. check-in: 0da07d5b1e user: dgp tags: core-8-5-branch
12:58
Make sure SetFooFromAny routines react reasonably when passed a NULL interp. check-in: 2adc132d52 user: dgp tags: core-8-4-branch
12:07
merge-mark check-in: d6aef45cc4 user: jan.nijtmans tags: core-8-5-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.












1
2
3
4
5
6
7











2011-04-21  Jan Nijtmans  <[email protected]>

	* generic/tcl.h:       fix for [Bug 3288345]: Wrong Tcl_StatBuf
	* generic/tclInt.h:    used on MinGW. Make sure that all _WIN32
	* win/tclWinFile.c:    compilers use exactly the same layout
	* win/configure.in:    for Tcl_StatBuf - the one used by MSVC6 -
	* win/configure:       in all situations.
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2011-04-21  Don Porter  <[email protected]>

	* generic/tclCompile.c:	Make sure SetFooFromAny routines react
	* generic/tclIO.c:	reasonably when passed a NULL interp.
	* generic/tclIndexObj.c:
	* generic/tclListObj.c:
	* generic/tclNamesp.c:
	* generic/tclObj.c:
	* generic/tclProc.c:
	* macosx/tclMacOSXFCmd.c:

2011-04-21  Jan Nijtmans  <[email protected]>

	* generic/tcl.h:       fix for [Bug 3288345]: Wrong Tcl_StatBuf
	* generic/tclInt.h:    used on MinGW. Make sure that all _WIN32
	* win/tclWinFile.c:    compilers use exactly the same layout
	* win/configure.in:    for Tcl_StatBuf - the one used by MSVC6 -
	* win/configure:       in all situations.

Changes to generic/tclCompile.c.

450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468
469
 *
 * TclSetByteCodeFromAny --
 *
 *	Part of the bytecode Tcl object type implementation. Attempts to
 *	generate an byte code internal form for the Tcl object "objPtr" by
 *	compiling its string representation. This function also takes a hook
 *	procedure that will be invoked to perform any needed post processing
 *	on the compilation results before generating byte codes.

 *
 * Results:
 *	The return value is a standard Tcl object result. If an error occurs
 *	during compilation, an error message is left in the interpreter's
 *	result unless "interp" is NULL.
 *
 * Side effects:
 *	Frees the old internal representation. If no error occurs, then the
 *	compiled code is stored as "objPtr"s bytecode representation. Also, if
 *	debugging, initializes the "tcl_traceCompile" Tcl variable used to
 *	trace compilations.
 *







|
>




|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
 *
 * TclSetByteCodeFromAny --
 *
 *	Part of the bytecode Tcl object type implementation. Attempts to
 *	generate an byte code internal form for the Tcl object "objPtr" by
 *	compiling its string representation. This function also takes a hook
 *	procedure that will be invoked to perform any needed post processing
 *	on the compilation results before generating byte codes. interp is
 *	compilation context and may not be NULL.
 *
 * Results:
 *	The return value is a standard Tcl object result. If an error occurs
 *	during compilation, an error message is left in the interpreter's
 *	result.
 *
 * Side effects:
 *	Frees the old internal representation. If no error occurs, then the
 *	compiled code is stored as "objPtr"s bytecode representation. Also, if
 *	debugging, initializes the "tcl_traceCompile" Tcl variable used to
 *	trace compilations.
 *
612
613
614
615
616
617
618



619
620
621
622
623
624
625

static int
SetByteCodeFromAny(
    Tcl_Interp *interp,		/* The interpreter for which the code is being
				 * compiled. Must not be NULL. */
    Tcl_Obj *objPtr)		/* The object to make a ByteCode object. */
{



    (void) TclSetByteCodeFromAny(interp, objPtr, NULL, (ClientData) NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *







>
>
>







613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

static int
SetByteCodeFromAny(
    Tcl_Interp *interp,		/* The interpreter for which the code is being
				 * compiled. Must not be NULL. */
    Tcl_Obj *objPtr)		/* The object to make a ByteCode object. */
{
    if (interp == NULL) {
	return TCL_ERROR;
    }
    (void) TclSetByteCodeFromAny(interp, objPtr, NULL, (ClientData) NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *

Changes to generic/tclIO.c.

10737
10738
10739
10740
10741
10742
10743



10744
10745
10746
10747
10748
10749
10750
SetChannelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    ChannelState *statePtr;
    Interp       *interpPtr;




    if (objPtr->typePtr == &tclChannelType) {
	/*
	 * The channel is valid until any call to DetachChannel occurs.
	 * Ensure consistency checks are done.
	 */
	statePtr  = GET_CHANNELSTATE(objPtr);
	interpPtr = GET_CHANNELINTERP(objPtr);







>
>
>







10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
SetChannelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    ChannelState *statePtr;
    Interp       *interpPtr;

    if (interp == NULL) {
	return TCL_ERROR;
    }
    if (objPtr->typePtr == &tclChannelType) {
	/*
	 * The channel is valid until any call to DetachChannel occurs.
	 * Ensure consistency checks are done.
	 */
	statePtr  = GET_CHANNELSTATE(objPtr);
	interpPtr = GET_CHANNELINTERP(objPtr);

Changes to generic/tclIndexObj.c.

299
300
301
302
303
304
305

306
307
308

309
310
311
312
313
314
315
 */

static int
SetIndexFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{

    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "can't convert value to index except via Tcl_GetIndexFromObj API",
	    -1));

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfIndex --







>



>







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
 */

static int
SetIndexFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    if (interp) {
    Tcl_SetObjResult(interp, Tcl_NewStringObj(
	    "can't convert value to index except via Tcl_GetIndexFromObj API",
	    -1));
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateStringOfIndex --

Changes to generic/tclListObj.c.

1689
1690
1691
1692
1693
1694
1695

1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
	 * representation) we also know that fetching the size of the
	 * dictionary or iterating over it will not fail.
	 */

	Tcl_DictObjSize(NULL, objPtr, &size);
	listRepPtr = NewListIntRep(size > 0 ? 2*size : 1, NULL);
	if (!listRepPtr) {

	    Tcl_SetResult(interp,
		    "insufficient memory to allocate list working space",
		    TCL_STATIC);

	    return TCL_ERROR;
	}
	listRepPtr->elemCount = 2 * size;

	/*
	 * Populate the list representation.
	 */







>
|
|
|
>







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
	 * representation) we also know that fetching the size of the
	 * dictionary or iterating over it will not fail.
	 */

	Tcl_DictObjSize(NULL, objPtr, &size);
	listRepPtr = NewListIntRep(size > 0 ? 2*size : 1, NULL);
	if (!listRepPtr) {
	    if (interp) {
		Tcl_SetResult(interp,
			"insufficient memory to allocate list working space",
			TCL_STATIC);
	    }
	    return TCL_ERROR;
	}
	listRepPtr->elemCount = 2 * size;

	/*
	 * Populate the list representation.
	 */
1749
1750
1751
1752
1753
1754
1755

1756
1757

1758
1759
1760
1761
1762
1763
1764
     * Each element is a pointer to a Tcl_Obj with the appropriate string rep.
     * The initial "estCount" elements are set using the corresponding "argv"
     * strings.
     */

    listRepPtr = NewListIntRep(estCount, NULL);
    if (!listRepPtr) {

	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"Not enough memory to allocate the list internal rep", -1));

	return TCL_ERROR;
    }
    elemPtrs = &listRepPtr->elements;

    for (p=string, lenRemain=length, i=0;
	    lenRemain > 0;
	    p=nextElem, lenRemain=limit-nextElem, i++) {







>
|
|
>







1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
     * Each element is a pointer to a Tcl_Obj with the appropriate string rep.
     * The initial "estCount" elements are set using the corresponding "argv"
     * strings.
     */

    listRepPtr = NewListIntRep(estCount, NULL);
    if (!listRepPtr) {
	if (interp) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Not enough memory to allocate the list internal rep", -1));
	}
	return TCL_ERROR;
    }
    elemPtrs = &listRepPtr->elements;

    for (p=string, lenRemain=length, i=0;
	    lenRemain > 0;
	    p=nextElem, lenRemain=limit-nextElem, i++) {

Changes to generic/tclNamesp.c.

4677
4678
4679
4680
4681
4682
4683
4684
4685





4686
4687
4688
4689
4690
4691
4692
				 * name. Also used for error reporting if not
				 * NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    const char *dummy;
    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
    register ResolvedNsName *resNamePtr;
    const char *name = TclGetString(objPtr);






    TclGetNamespaceForQualName(interp, name, NULL, TCL_FIND_ONLY_NS,
	     &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);

    /*
     * If we found a namespace, then create a new ResolvedNsName structure
     * that holds a reference to it.
     */







|

>
>
>
>
>







4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
				 * name. Also used for error reporting if not
				 * NULL. */
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    const char *dummy;
    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
    register ResolvedNsName *resNamePtr;
    const char *name;

    if (interp == NULL) {
	return TCL_ERROR;
    }

    name = TclGetString(objPtr);
    TclGetNamespaceForQualName(interp, name, NULL, TCL_FIND_ONLY_NS,
	     &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);

    /*
     * If we found a namespace, then create a new ResolvedNsName structure
     * that holds a reference to it.
     */

Changes to generic/tclObj.c.

4259
4260
4261
4262
4263
4264
4265




4266
4267
4268
4269
4270
4271
4272
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    Interp *iPtr = (Interp *) interp;
    char *name;
    register Command *cmdPtr;
    Namespace *currNsPtr;
    register ResolvedCmdName *resPtr;





    /*
     * Find the Command structure, if any, that describes the command called
     * "name". Build a ResolvedCmdName that holds a cached pointer to this
     * Command, and bump the reference count in the referenced Command
     * structure. A Command structure will not be deleted as long as it is
     * referenced from a CmdName object.







>
>
>
>







4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    Interp *iPtr = (Interp *) interp;
    char *name;
    register Command *cmdPtr;
    Namespace *currNsPtr;
    register ResolvedCmdName *resPtr;

    if (interp == NULL) {
	return TCL_ERROR;
    }

    /*
     * Find the Command structure, if any, that describes the command called
     * "name". Build a ResolvedCmdName that holds a cached pointer to this
     * Command, and bump the reference count in the referenced Command
     * structure. A Command structure will not be deleted as long as it is
     * referenced from a CmdName object.

Changes to generic/tclProc.c.

2442
2443
2444
2445
2446
2447
2448




2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    Interp *iPtr = (Interp *) interp;
    char *name;
    Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv, *errPtr;
    int objc, result;
    Proc *procPtr;





    /*
     * Convert objPtr to list type first; if it cannot be converted, or if its
     * length is not 2, then it cannot be converted to lambdaType.
     */

    result = TclListObjGetElements(interp, objPtr, &objc, &objv);
    if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) {
	TclNewLiteralStringObj(errPtr, "can't interpret \"");
	Tcl_AppendObjToObj(errPtr, objPtr);
	Tcl_AppendToObj(errPtr, "\" as a lambda expression", -1);
	Tcl_SetObjResult(interp, errPtr);
	return TCL_ERROR;
    }







>
>
>
>






|







2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
    register Tcl_Obj *objPtr)	/* The object to convert. */
{
    Interp *iPtr = (Interp *) interp;
    char *name;
    Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv, *errPtr;
    int objc, result;
    Proc *procPtr;

    if (interp == NULL) {
	return TCL_ERROR;
    }

    /*
     * Convert objPtr to list type first; if it cannot be converted, or if its
     * length is not 2, then it cannot be converted to lambdaType.
     */

    result = TclListObjGetElements(NULL, objPtr, &objc, &objv);
    if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) {
	TclNewLiteralStringObj(errPtr, "can't interpret \"");
	Tcl_AppendObjToObj(errPtr, objPtr);
	Tcl_AppendToObj(errPtr, "\" as a lambda expression", -1);
	Tcl_SetObjResult(interp, errPtr);
	return TCL_ERROR;
    }

Changes to macosx/tclMacOSXFCmd.c.

619
620
621
622
623
624
625

626
627

628
629
630
631
632
633
634
    Tcl_DString ds;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

    string = Tcl_GetStringFromObj(objPtr, &length);
    Tcl_UtfToExternalDString(encoding, string, length, &ds);

    if (Tcl_DStringLength(&ds) > 4) {

	Tcl_AppendResult(interp, "expected Macintosh OS type but got \"",
		string, "\": ", NULL);

	result = TCL_ERROR;
    } else {
	OSType osType;
	char string[4] = {'\0','\0','\0','\0'};
	memcpy(string, Tcl_DStringValue(&ds),
		(size_t) Tcl_DStringLength(&ds));
	osType = (OSType) string[0] << 24 |







>
|
|
>







619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    Tcl_DString ds;
    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");

    string = Tcl_GetStringFromObj(objPtr, &length);
    Tcl_UtfToExternalDString(encoding, string, length, &ds);

    if (Tcl_DStringLength(&ds) > 4) {
	if (interp) {
	    Tcl_AppendResult(interp, "expected Macintosh OS type but got \"",
		    string, "\": ", NULL);
	}
	result = TCL_ERROR;
    } else {
	OSType osType;
	char string[4] = {'\0','\0','\0','\0'};
	memcpy(string, Tcl_DStringValue(&ds),
		(size_t) Tcl_DStringLength(&ds));
	osType = (OSType) string[0] << 24 |