Skip to content

Commit 6ab9ff9

Browse files
committed
Check for inf/nan in timedelta constructor
1 parent d50a4f3 commit 6ab9ff9

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

src/core/IronPython.Modules/_datetime.cs

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ internal timedelta(TimeSpan ts, double microsecond)
5454
}
5555

5656
public timedelta(double days, double seconds, double microseconds, double milliseconds, double minutes, double hours, double weeks) {
57-
double totalDays = weeks * 7 + days;
58-
double totalSeconds = ((totalDays * 24 + hours) * 60 + minutes) * 60 + seconds;
57+
double totalSeconds = (((weeks * 7 + days) * 24 + hours) * 60 + minutes) * 60 + seconds;
58+
CheckDouble(totalSeconds);
5959

6060
double totalSecondsSharp = Math.Floor(totalSeconds);
6161
double totalSecondsFloat = totalSeconds - totalSecondsSharp;
6262

6363
double totalMicroseconds = Math.Round(totalSecondsFloat * 1e6 + milliseconds * 1000 + microseconds);
64+
CheckDouble(totalMicroseconds);
65+
6466
double otherSecondsFromMicroseconds = Math.Floor(totalMicroseconds / 1e6);
6567

6668
totalSecondsSharp += otherSecondsFromMicroseconds;
@@ -71,28 +73,45 @@ public timedelta(double days, double seconds, double microseconds, double millis
7173
totalMicroseconds += 1e6;
7274
}
7375

74-
_days = (int)(totalSecondsSharp / SECONDSPERDAY);
75-
_seconds = (int)(totalSecondsSharp - _days * SECONDSPERDAY);
76+
_days = ToInt(totalSecondsSharp / SECONDSPERDAY);
77+
_seconds = ToInt(totalSecondsSharp - _days * SECONDSPERDAY);
7678

7779
if (_seconds < 0) {
7880
_days--;
7981
_seconds += (int)SECONDSPERDAY;
8082
}
81-
_microseconds = (int)(totalMicroseconds);
83+
_microseconds = ToInt(totalMicroseconds);
8284

8385
if (Math.Abs(_days) > MAXDAYS) {
8486
throw PythonOps.OverflowError("days={0}; must have magnitude <= 999999999", _days);
8587
}
88+
89+
static void CheckDouble(double d) {
90+
if (double.IsInfinity(d)) {
91+
throw PythonOps.OverflowError("cannot convert float infinity to integer");
92+
} else if (double.IsNaN(d)) {
93+
throw PythonOps.ValueError("cannot convert float NaN to integer");
94+
}
95+
}
96+
97+
static int ToInt(double d) {
98+
if (Int32.MinValue <= d && d <= Int32.MaxValue) {
99+
return (int)d;
100+
} else {
101+
CheckDouble(d);
102+
return checked((int)d);
103+
}
104+
}
86105
}
87106

88107
public static timedelta __new__(CodeContext context, [NotNone] PythonType cls,
89-
double days = 0D,
90-
double seconds = 0D,
91-
double microseconds = 0D,
92-
double milliseconds = 0D,
93-
double minutes = 0D,
94-
double hours = 0D,
95-
double weeks = 0D) {
108+
double days = 0,
109+
double seconds = 0,
110+
double microseconds = 0,
111+
double milliseconds = 0,
112+
double minutes = 0,
113+
double hours = 0,
114+
double weeks = 0) {
96115
if (cls == DynamicHelpers.GetPythonTypeFromType(typeof(timedelta))) {
97116
return new timedelta(days, seconds, microseconds, milliseconds, minutes, hours, weeks);
98117
} else {

0 commit comments

Comments
 (0)