Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit d66ee36

Browse files
committed
Fix TimeSpanConverter overflow
1 parent 523be85 commit d66ee36

File tree

2 files changed

+27
-18
lines changed

2 files changed

+27
-18
lines changed

src/ServiceStack.Text/Support/TimeSpanConverter.cs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ public static string ToXsdDuration(TimeSpan timeSpan)
1414

1515
double ticks = Math.Abs(timeSpan.Ticks);
1616
double totalSeconds = ticks / TimeSpan.TicksPerSecond;
17-
int wholeSeconds = (int) totalSeconds;
18-
int seconds = wholeSeconds;
19-
int sec = (seconds >= 60 ? seconds % 60 : seconds);
20-
int min = (seconds = (seconds / 60)) >= 60 ? seconds % 60 : seconds;
21-
int hours = (seconds = (seconds / 60)) >= 24 ? seconds % 24 : seconds;
22-
int days = seconds / 24;
17+
long wholeSeconds = (long) totalSeconds;
18+
long seconds = wholeSeconds;
19+
long sec = (seconds >= 60 ? seconds % 60 : seconds);
20+
long min = (seconds = (seconds / 60)) >= 60 ? seconds % 60 : seconds;
21+
long hours = (seconds = (seconds / 60)) >= 24 ? seconds % 24 : seconds;
22+
long days = seconds / 24;
2323
double remainingSecs = sec + (totalSeconds - wholeSeconds);
2424

2525
if (days > 0)
@@ -51,11 +51,11 @@ public static string ToXsdDuration(TimeSpan timeSpan)
5151

5252
public static TimeSpan FromXsdDuration(string xsdDuration)
5353
{
54-
int days = 0;
55-
int hours = 0;
56-
int minutes = 0;
54+
long days = 0;
55+
long hours = 0;
56+
long minutes = 0;
5757
decimal seconds = 0;
58-
int sign = 1;
58+
long sign = 1;
5959

6060
if (xsdDuration.StartsWith("-", StringComparison.Ordinal))
6161
{
@@ -70,33 +70,29 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
7070
string[] d = t[0].SplitOnFirst('D');
7171
if (d.Length == 2)
7272
{
73-
int day;
74-
if (int.TryParse(d[0], out day))
73+
if (long.TryParse(d[0], out var day))
7574
days = day;
7675
}
7776
if (hasTime)
7877
{
7978
string[] h = t[1].SplitOnFirst('H');
8079
if (h.Length == 2)
8180
{
82-
int hour;
83-
if (int.TryParse(h[0], out hour))
81+
if (long.TryParse(h[0], out var hour))
8482
hours = hour;
8583
}
8684

8785
string[] m = h[h.Length - 1].SplitOnFirst('M');
8886
if (m.Length == 2)
8987
{
90-
int min;
91-
if (int.TryParse(m[0], out min))
88+
if (long.TryParse(m[0], out var min))
9289
minutes = min;
9390
}
9491

9592
string[] s = m[m.Length - 1].SplitOnFirst('S');
9693
if (s.Length == 2)
9794
{
98-
decimal millis;
99-
if (decimal.TryParse(s[0], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out millis))
95+
if (decimal.TryParse(s[0], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var millis))
10096
seconds = millis;
10197
}
10298
}

tests/ServiceStack.Text.Tests/TimeSpanConverterTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class TimeSpanConverterTests
1717
private readonly TimeSpan oneMilliSecond = new TimeSpan(0, 0, 0, 0, 1);
1818
private readonly TimeSpan oneDayHourMinuteSecondMilliSecond = new TimeSpan(1, 1, 1, 1, 1);
1919
private readonly TimeSpan threeThousandSixHundredAndFiveDays = TimeSpan.FromDays(3605);
20+
private readonly TimeSpan ninetyThousandDays = TimeSpan.FromDays(90000);
2021
private readonly TimeSpan arbitraryTimeSpan = new TimeSpan(1, 2, 3, 4, 567).Add(TimeSpan.FromTicks(1));
2122

2223
[Test]
@@ -48,6 +49,9 @@ public void Can_Serialize_TimeSpan()
4849

4950
Assert.That(TimeSpanConverter.ToXsdDuration(threeThousandSixHundredAndFiveDays), Is.EqualTo("P3605D"));
5051
Assert.That(TimeSpanConverter.ToXsdDuration(-threeThousandSixHundredAndFiveDays), Is.EqualTo("-P3605D"));
52+
53+
Assert.That(TimeSpanConverter.ToXsdDuration(ninetyThousandDays), Is.EqualTo("P90000D"));
54+
Assert.That(TimeSpanConverter.ToXsdDuration(-ninetyThousandDays), Is.EqualTo("-P90000D"));
5155
}
5256

5357
[Test]
@@ -80,6 +84,9 @@ public void Can_deserialize_TimeSpan()
8084

8185
Assert.That(TimeSpanConverter.FromXsdDuration("P3605D"), Is.EqualTo(threeThousandSixHundredAndFiveDays));
8286
Assert.That(TimeSpanConverter.FromXsdDuration("-P3605D"), Is.EqualTo(-threeThousandSixHundredAndFiveDays));
87+
88+
Assert.That(TimeSpanConverter.FromXsdDuration("P90000D"), Is.EqualTo(ninetyThousandDays));
89+
Assert.That(TimeSpanConverter.FromXsdDuration("-P90000D"), Is.EqualTo(-ninetyThousandDays));
8390
}
8491

8592
[Test]
@@ -111,6 +118,9 @@ public void Can_Serialize_TimeSpan_DifferentCulture()
111118

112119
Assert.That(TimeSpanConverter.ToXsdDuration(threeThousandSixHundredAndFiveDays), Is.EqualTo("P3605D"));
113120
Assert.That(TimeSpanConverter.ToXsdDuration(-threeThousandSixHundredAndFiveDays), Is.EqualTo("-P3605D"));
121+
122+
Assert.That(TimeSpanConverter.ToXsdDuration(ninetyThousandDays), Is.EqualTo("P90000D"));
123+
Assert.That(TimeSpanConverter.ToXsdDuration(-ninetyThousandDays), Is.EqualTo("-P90000D"));
114124
}
115125

116126
[Test]
@@ -143,6 +153,9 @@ public void Can_deserialize_TimeSpan_DifferentCulture()
143153

144154
Assert.That(TimeSpanConverter.FromXsdDuration("P3605D"), Is.EqualTo(threeThousandSixHundredAndFiveDays));
145155
Assert.That(TimeSpanConverter.FromXsdDuration("-P3605D"), Is.EqualTo(-threeThousandSixHundredAndFiveDays));
156+
157+
Assert.That(TimeSpanConverter.FromXsdDuration("P90000D"), Is.EqualTo(ninetyThousandDays));
158+
Assert.That(TimeSpanConverter.FromXsdDuration("-P90000D"), Is.EqualTo(-ninetyThousandDays));
146159
}
147160
}
148161
}

0 commit comments

Comments
 (0)