Skip to content

Commit bdbad0d

Browse files
authored
Two bugs of iCal parsing was fixed (#424)
1 parent 1f83631 commit bdbad0d

File tree

3 files changed

+91
-13
lines changed

3 files changed

+91
-13
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
using nanoFramework.TestFramework;
7+
using System;
8+
9+
namespace nanoFramework.Json.Test
10+
{
11+
[TestClass]
12+
public class DateTimeExtensionsTests
13+
{
14+
[TestMethod]
15+
[DataRow("19990101T000000")]
16+
[DataRow("20001120T221530")]
17+
[DataRow("20250706T005433")]
18+
[DataRow("16010101T000000")]
19+
[DataRow("30001231T235958")]
20+
public void FromiCalendar_LocalTime_ShouldNotBeMaxValue(string iCal)
21+
{
22+
var act = DateTimeExtensions.FromiCalendar(iCal);
23+
24+
Assert.AreNotEqual(DateTime.MaxValue, act);
25+
}
26+
27+
[TestMethod]
28+
[DataRow("19990101T000000Z")]
29+
[DataRow("20001120T221530Z")]
30+
[DataRow("20250706T005433Z")]
31+
[DataRow("16010101T000000Z")]
32+
[DataRow("30001231T235958Z")]
33+
public void FromiCalendar_UtcTime_ShouldNotBeMaxValue(string iCal)
34+
{
35+
var act = DateTimeExtensions.FromiCalendar(iCal);
36+
37+
Assert.AreNotEqual(DateTime.MaxValue, act);
38+
}
39+
40+
[TestMethod]
41+
[DataRow("12345678901234567890")]
42+
[DataRow("3333333333333333")]
43+
[DataRow("444444444444444")]
44+
[DataRow("12345678T901234")]
45+
[DataRow("000000000000000")]
46+
[DataRow("test")]
47+
[DataRow("test19990101T000000Z")]
48+
[DataRow("test0101T000000Z")]
49+
[DataRow("test19990101T000000")]
50+
[DataRow("test0101T000000")]
51+
[DataRow("_!123@1903$#*((")]
52+
public void FromiCalendar_NotATime_ShuldReturnMaxValue(string iCal)
53+
{
54+
var act = DateTimeExtensions.FromiCalendar(iCal);
55+
56+
Assert.AreEqual(DateTime.MaxValue, act);
57+
}
58+
}
59+
}

nanoFramework.Json.Test/nanoFramework.Json.Test.nfproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<Compile Include="Converters\FloatConverterTests.cs" />
5050
<Compile Include="Converters\DoubleConverterTests.cs" />
5151
<Compile Include="Configuration\JsonCustomTypeTests.cs" />
52+
<Compile Include="DateTimeExtensionsTests.cs" />
5253
<Compile Include="JsonDeserializationArraysTests.cs" />
5354
<Compile Include="JsonSettingsTests.cs" />
5455
<Compile Include="JsonThreadSafeTests.cs" />

nanoFramework.Json/TimeExtensions.cs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ public static DateTime FromiCalendar(string iCalendar)
5555
time = result; // localtime
5656
}
5757

58+
if (time.Length < 15)
59+
{
60+
return DateTime.MaxValue;
61+
}
62+
5863
// We now have the time string to parse, and we'll adjust
5964
// to UTC or timezone after parsing
6065
string year = time.Substring(0, 4);
@@ -65,43 +70,56 @@ public static DateTime FromiCalendar(string iCalendar)
6570
string second = time.Substring(13, 2);
6671

6772
// Check if any of the date time parts is non-numeric
68-
if (!IsNumeric(year))
73+
if (!int.TryParse(year, out int intYear) ||
74+
intYear < DateTime.MinValue.Year ||
75+
intYear > DateTime.MaxValue.Year)
6976
{
7077
return DateTime.MaxValue;
7178
}
72-
else if (!IsNumeric(month))
79+
if (!int.TryParse(month, out int intMonth) ||
80+
intMonth < DateTime.MinValue.Month ||
81+
intMonth > DateTime.MaxValue.Month)
7382
{
7483
return DateTime.MaxValue;
7584
}
76-
else if (!IsNumeric(day))
85+
if (!int.TryParse(day, out int intDay) ||
86+
intDay < DateTime.MinValue.Day ||
87+
intDay > DateTime.MaxValue.Day ||
88+
intDay > DateTime.DaysInMonth(intYear, intMonth))
7789
{
7890
return DateTime.MaxValue;
7991
}
80-
else if (!IsNumeric(hour))
92+
if (!int.TryParse(hour, out int intHour) ||
93+
intHour < DateTime.MinValue.Hour ||
94+
intHour > DateTime.MaxValue.Hour)
8195
{
8296
return DateTime.MaxValue;
8397
}
84-
else if (!IsNumeric(minute))
98+
if (!int.TryParse(minute, out int intMinute) ||
99+
intMinute < DateTime.MinValue.Minute ||
100+
intMinute > DateTime.MaxValue.Minute)
85101
{
86102
return DateTime.MaxValue;
87103
}
88-
else if (!IsNumeric(second))
104+
if (!int.TryParse(second, out int intSecond) ||
105+
intSecond < DateTime.MinValue.Second ||
106+
intSecond > DateTime.MaxValue.Second)
89107
{
90108
return DateTime.MaxValue;
91109
}
92110

93111
DateTime dt = new(
94-
Convert.ToInt32(year),
95-
Convert.ToInt32(month),
96-
Convert.ToInt32(day),
97-
Convert.ToInt32(hour),
98-
Convert.ToInt32(minute),
99-
Convert.ToInt32(second));
112+
intYear,
113+
intMonth,
114+
intDay,
115+
intHour,
116+
intMinute,
117+
intSecond);
100118

101119
if (utc)
102120
{
103121
// Convert the Kind to DateTimeKind.Utc
104-
dt = new DateTime(0, DateTimeKind.Utc).AddTicks(dt.Ticks);
122+
dt = new DateTime(dt.Ticks, DateTimeKind.Utc);
105123
}
106124
else if (tzid)
107125
{

0 commit comments

Comments
 (0)