diff options
author | sebres <sebres@users.sourceforge.net> | 2024-03-12 01:48:02 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2024-03-12 01:48:02 (GMT) |
commit | fad9db2aa8c6d3cd97eb4356867afaf34d1c25de (patch) | |
tree | 449a81fb97d51afa108cdc6e7dd111c7d9dd3ca3 /generic | |
parent | dccb8e0210ddfab7f05e981bcc0a8bfbe1f3678b (diff) | |
download | tcl-fad9db2aa8c6d3cd97eb4356867afaf34d1c25de.zip tcl-fad9db2aa8c6d3cd97eb4356867afaf34d1c25de.tar.gz tcl-fad9db2aa8c6d3cd97eb4356867afaf34d1c25de.tar.bz2 |
fixes #23: `clock add` regression (integer overflow in time part)
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclClock.c | 15 | ||||
-rw-r--r-- | generic/tclDate.h | 12 |
2 files changed, 15 insertions, 12 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c index 571052f..76f14da 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -4189,7 +4189,7 @@ repeat_rel: /* relative time (seconds), if exceeds current date, do the day conversion and * leave rest of the increment in yyRelSeconds to add it hereafter in UTC seconds */ if (yyRelSeconds) { - int newSecs = yySecondOfDay + yyRelSeconds; + Tcl_WideInt newSecs = yySecondOfDay + yyRelSeconds; /* if seconds increment outside of current date, increment day */ if (newSecs / SECONDS_PER_DAY != yySecondOfDay / SECONDS_PER_DAY) { @@ -4434,19 +4434,22 @@ ClockAddObjCmd( */ for (i = 2; i < objc; i+=2) { - /* bypass not integers (options, allready processed above) */ + /* bypass not integers (options, allready processed above in ClockParseFmtScnArgs) */ if (TclGetWideIntFromObj(NULL, objv[i], &offs) != TCL_OK) { continue; } - if (objv[i]->typePtr == &tclBignumType) { - Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); - goto done; - } /* get unit */ if (Tcl_GetIndexFromObj(interp, objv[i+1], units, "unit", 0, &unitIndex) != TCL_OK) { goto done; } + if (objv[i]->typePtr == &tclBignumType + || offs > (unitIndex < CLC_ADD_HOURS ? 0x7fffffff : TCL_MAX_SECONDS) + || offs < (unitIndex < CLC_ADD_HOURS ? -0x7fffffff : TCL_MIN_SECONDS) + ) { + Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); + goto done; + } /* nothing to do if zero quantity */ if (!offs) { diff --git a/generic/tclDate.h b/generic/tclDate.h index 465473f..10e6473 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -174,8 +174,8 @@ typedef struct TclDateFields { int dayOfWeek; /* Day of the week */ int hour; /* Hours of day (in-between time only calculation) */ int minutes; /* Minutes of hour (in-between time only calculation) */ - int secondOfMin; /* Seconds of minute (in-between time only calculation) */ - int secondOfDay; /* Seconds of day (in-between time only calculation) */ + Tcl_WideInt secondOfMin; /* Seconds of minute (in-between time only calculation) */ + Tcl_WideInt secondOfDay; /* Seconds of day (in-between time only calculation) */ int flags; /* 0 or CLF_CTZ */ @@ -215,16 +215,16 @@ typedef struct DateInfo { int dateTimezone; int dateDSTmode; - int dateRelMonth; - int dateRelDay; - int dateRelSeconds; + Tcl_WideInt dateRelMonth; + Tcl_WideInt dateRelDay; + Tcl_WideInt dateRelSeconds; int dateMonthOrdinalIncr; int dateMonthOrdinal; int dateDayOrdinal; - int *dateRelPointer; + Tcl_WideInt *dateRelPointer; int dateSpaceCount; int dateDigitCount; |