Skip to content

Commit

Permalink
Merge branch 'fix-gh-23--clock-add-int-ovflw', fixes clock add (and…
Browse files Browse the repository at this point in the history
… `clock scan`) regression #23 - int overflow on large relative units
  • Loading branch information
sebres committed Jan 13, 2023
2 parents 50fe01c + c66eee9 commit fd01584
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 16 deletions.
15 changes: 9 additions & 6 deletions generic/tclClock.c
Original file line number Diff line number Diff line change
Expand Up @@ -4173,7 +4173,7 @@ ClockCalcRelTime(
/* 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) {
Expand Down Expand Up @@ -4418,19 +4418,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 == tclBignumTypePtr) {
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 == tclBignumTypePtr
|| 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) {
Expand Down
4 changes: 2 additions & 2 deletions generic/tclDate.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
typedef struct _TABLE {
const char *name;
int type;
long value;
Tcl_WideInt value;
} TABLE;

/*
Expand Down Expand Up @@ -224,7 +224,7 @@ extern int TclDatedebug;
union YYSTYPE
{

long Number;
Tcl_WideInt Number;
enum _MERIDIAN Meridian;


Expand Down
12 changes: 6 additions & 6 deletions generic/tclDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,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 */

Expand Down Expand Up @@ -244,16 +244,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;
Expand Down
4 changes: 2 additions & 2 deletions generic/tclGetDate.y
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
typedef struct _TABLE {
const char *name;
int type;
long value;
Tcl_WideInt value;
} TABLE;

/*
Expand All @@ -103,7 +103,7 @@ typedef enum _DSTMODE {
%}

%union {
long Number;
Tcl_WideInt Number;
enum _MERIDIAN Meridian;
}

Expand Down
60 changes: 60 additions & 0 deletions tests/clock.test
Original file line number Diff line number Diff line change
Expand Up @@ -35737,6 +35737,44 @@ test clock-30.30 {clock add weekdays and back} -body {
}
return "OK"
} -result {OK}
test clock-30.31 {regression test - add no int overflow} {
list \
[list \
[clock add 0 1600000000 seconds 24856 days -gmt 1] \
[clock add 0 1600000000 seconds 815 months -gmt 1] \
[clock add 0 1600000000 seconds 69 years -gmt 1] \
[clock add 0 1600000000 seconds 596524 hours -gmt 1] \
[clock add 0 1600000000 seconds 35791395 minutes -gmt 1] \
[clock add 0 1600000000 seconds 0x7fffffff seconds -gmt 1]
] \
[list \
[clock add 1600000000 24856 days -gmt 1] \
[clock add 1600000000 815 months -gmt 1] \
[clock add 1600000000 69 years -gmt 1] \
[clock add 1600000000 596524 hours -gmt 1] \
[clock add 1600000000 35791395 minutes -gmt 1] \
[clock add 1600000000 0x7fffffff seconds -gmt 1]
]
} [lrepeat 2 {3747558400 3743238400 3777452800 3747486400 3747483700 3747483647}]
test clock-30.32 {regression test - add no int overflow} {
list \
[list \
[clock add 3777452800 -1600000000 seconds -24856 days -gmt 1] \
[clock add 3777452800 -1600000000 seconds -815 months -gmt 1] \
[clock add 3777452800 -1600000000 seconds -69 years -gmt 1] \
[clock add 3777452800 -1600000000 seconds -596524 hours -gmt 1] \
[clock add 3777452800 -1600000000 seconds -35791395 minutes -gmt 1] \
[clock add 3777452800 -1600000000 seconds -0x7fffffff seconds -gmt 1]
] \
[list \
[clock add 2177452800 -24856 days -gmt 1] \
[clock add 2177452800 -815 months -gmt 1] \
[clock add 2177452800 -69 years -gmt 1] \
[clock add 2177452800 -596524 hours -gmt 1] \
[clock add 2177452800 -35791395 minutes -gmt 1] \
[clock add 2177452800 -0x7fffffff seconds -gmt 1]
]
} [lrepeat 2 {29894400 34214400 0 29966400 29969100 29969153}]

# END testcases30

Expand Down Expand Up @@ -36902,6 +36940,28 @@ test clock-45.4 {compat: scan regression on spaces (mandatory leading/trailing s
[catch {clock scan "11 1 120" -format " %y%m%d %H%M%S" -gmt 1} ret] $ret \
[catch {clock scan "11 1 120" -format " %y%m%d %H%M%S " -gmt 1} ret] $ret
} -result [lrepeat 3 1 "input string does not match supplied format"]
test clock-45.5 {regression test - freescan no int overflow} {
# note that the relative date changes currently reset the time to 00:00,
# this can be changed later (simply achievable by adding 00:00 if expected):
list \
[clock scan "+24856 days" -base 1600000000 -gmt 1] \
[clock scan "+815 months" -base 1600000000 -gmt 1] \
[clock scan "+69 years" -base 1600000000 -gmt 1] \
[clock scan "+596524 hours" -base 1600000000 -gmt 1] \
[clock scan "+35791395 minutes" -base 1600000000 -gmt 1] \
[clock scan "+2147483647 seconds" -base 1600000000 -gmt 1]
} {3747513600 3743193600 3777408000 3747486400 3747483700 3747483647}
test clock-45.6 {regression test - freescan no int overflow} {
# note that the relative date changes currently reset the time to 00:00,
# this can be changed later (simply achievable by adding 00:00 if expected):
list \
[clock scan "-24856 days" -base 2177452800 -gmt 1] \
[clock scan "-815 months" -base 2177452800 -gmt 1] \
[clock scan "-69 years" -base 2177452800 -gmt 1] \
[clock scan "-596524 hours" -base 2177452800 -gmt 1] \
[clock scan "-35791395 minutes" -base 2177452800 -gmt 1] \
[clock scan "-2147483647 seconds" -base 2177452800 -gmt 1]
} {29894400 34214400 0 29966400 29969100 29969153}

test clock-46.1 {regression test - month zero} -constraints valid_off \
-body {
Expand Down

0 comments on commit fd01584

Please sign in to comment.