Tcl Source Code

Check-in [3c341011b9]
Login

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

Overview
Comment:Fix panic "loop in ConvertLocalToUTCUsingTable", introduced by previous commit. Some further code cleanup
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-branch
Files: files | file ages | folders
SHA3-256: 3c341011b9c6dc4b14c5636d4415bf215d445bcb2887a57ea111776ed4e93824
User & Date: jan.nijtmans 2024-04-12 09:46:25
Context
2024-04-12
13:25
More cleaning up, notably no more symbols starting with _ as they're a reserved 'namespace' check-in: bfb42faa67 user: dkf tags: core-8-branch
09:47
Merge 8.7 check-in: 95201cd0f6 user: jan.nijtmans tags: trunk, main
09:46
Fix panic "loop in ConvertLocalToUTCUsingTable", introduced by previous commit. Some further code cl... check-in: 3c341011b9 user: jan.nijtmans tags: core-8-branch
2024-04-11
16:14
Clean up the code style of the rest of clock check-in: 5e6e644645 user: dkf tags: core-8-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclClock.c.

2029
2030
2031
2032
2033
2034
2035
2036

2037
2038
2039
2040
2041
2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053
		    &cellv) != TCL_OK
		|| TclGetIntFromObj(interp, cellv[1],
		    &fields->tzOffset) != TCL_OK) {
	    return TCL_ERROR;
	}
	for (i = 0; i < nHave; ++i) {
	    if (have[i].tzOffset == fields->tzOffset) {
		break;

	    }
	}
	if (nHave == 8) {
	    Tcl_Panic("loop in ConvertLocalToUTCUsingTable");
	}
	have[nHave].tzName = cellv[3];
	have[nHave++].tzOffset = fields->tzOffset;
	fields->seconds = fields->localSeconds - fields->tzOffset;
    }


    fields->tzOffset = have[i].tzOffset;
    fields->seconds = fields->localSeconds - fields->tzOffset;
    TclSetObjRef(fields->tzName, have[i].tzName);

    return TCL_OK;
}








<
>










>







2029
2030
2031
2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
		    &cellv) != TCL_OK
		|| TclGetIntFromObj(interp, cellv[1],
		    &fields->tzOffset) != TCL_OK) {
	    return TCL_ERROR;
	}
	for (i = 0; i < nHave; ++i) {
	    if (have[i].tzOffset == fields->tzOffset) {

		goto found;
	    }
	}
	if (nHave == 8) {
	    Tcl_Panic("loop in ConvertLocalToUTCUsingTable");
	}
	have[nHave].tzName = cellv[3];
	have[nHave++].tzOffset = fields->tzOffset;
	fields->seconds = fields->localSeconds - fields->tzOffset;
    }

  found:
    fields->tzOffset = have[i].tzOffset;
    fields->seconds = fields->localSeconds - fields->tzOffset;
    TclSetObjRef(fields->tzName, have[i].tzName);

    return TCL_OK;
}

3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
    const time_t *timePtr)	/* Pointer to the number of seconds since the
				 * local system's epoch */
{
    /*
     * Get a thread-local buffer to hold the returned time.
     */

    struct tm *tmPtr = (struct tm *) Tcl_GetThreadData(&tmKey, sizeof(struct tm));
#ifdef HAVE_LOCALTIME_R
    tmPtr = localtime_r(timePtr, tmPtr);
#else
    struct tm *sysTmPtr;

    Tcl_MutexLock(&clockMutex);
    sysTmPtr = localtime(timePtr);







|







3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
    const time_t *timePtr)	/* Pointer to the number of seconds since the
				 * local system's epoch */
{
    /*
     * Get a thread-local buffer to hold the returned time.
     */

    struct tm *tmPtr = (struct tm *)Tcl_GetThreadData(&tmKey, sizeof(struct tm));
#ifdef HAVE_LOCALTIME_R
    tmPtr = localtime_r(timePtr, tmPtr);
#else
    struct tm *sysTmPtr;

    Tcl_MutexLock(&clockMutex);
    sysTmPtr = localtime(timePtr);
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678

    ret = ClockScanCommit(&yy, &opts);
    if (ret != TCL_OK) {
	goto done;
    }

    /* Apply remaining validation rules, if expected */
    if ((opts.flags & CLF_VALIDATE)) {
	ret = ClockValidDate(&yy, &opts, opts.flags & CLF_VALIDATE);
	if (ret != TCL_OK) {
	    goto done;
	}
    }

  done:







|







3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679

    ret = ClockScanCommit(&yy, &opts);
    if (ret != TCL_OK) {
	goto done;
    }

    /* Apply remaining validation rules, if expected */
    if (opts.flags & CLF_VALIDATE) {
	ret = ClockValidDate(&yy, &opts, opts.flags & CLF_VALIDATE);
	if (ret != TCL_OK) {
	    goto done;
	}
    }

  done:
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
	info->flags |= CLF_ASSEMBLE_SECONDS;
    }

    /*
     * For freescan apply validation rules (stage 1) before mixed with
     * relative time (otherwise always valid recalculated date & time).
     */
    if ((opts->flags & CLF_VALIDATE)) {
	if (ClockValidDate(info, opts, CLF_VALIDATE_S1) != TCL_OK) {
	    goto done;
	}
    }

    /*
     * Assemble date, time, zone into seconds-from-epoch







|







4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
	info->flags |= CLF_ASSEMBLE_SECONDS;
    }

    /*
     * For freescan apply validation rules (stage 1) before mixed with
     * relative time (otherwise always valid recalculated date & time).
     */
    if (opts->flags & CLF_VALIDATE) {
	if (ClockValidDate(info, opts, CLF_VALIDATE_S1) != TCL_OK) {
	    goto done;
	}
    }

    /*
     * Assemble date, time, zone into seconds-from-epoch
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
    InterpState *statePtr;

    if (objc == 1) {
	/* wrong # args : */
	return Tcl_CatchObjCmd(NULL, interp, objc, objv);
    }

    statePtr = (InterpState *) Tcl_SaveInterpState(interp, 0);
    if (!statePtr->errorInfo) {
	/* todo: avoid traced get of errorInfo here */
	TclInitObjRef(statePtr->errorInfo,
		Tcl_ObjGetVar2(interp, iPtr->eiVar, NULL, 0));
	flags |= ERR_LEGACY_COPY;
    }
    if (!statePtr->errorCode) {







|







4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
    InterpState *statePtr;

    if (objc == 1) {
	/* wrong # args : */
	return Tcl_CatchObjCmd(NULL, interp, objc, objv);
    }

    statePtr = (InterpState *)Tcl_SaveInterpState(interp, 0);
    if (!statePtr->errorInfo) {
	/* todo: avoid traced get of errorInfo here */
	TclInitObjRef(statePtr->errorInfo,
		Tcl_ObjGetVar2(interp, iPtr->eiVar, NULL, 0));
	flags |= ERR_LEGACY_COPY;
    }
    if (!statePtr->errorCode) {