Skip to content

Commit 1377e5e

Browse files
authored
Merge pull request #83405 from vseanreesermsft/internal-merge-7.0-2023-03-14-1018
Merging internal commits for release/7.0
2 parents 56da0d3 + b77565a commit 1377e5e

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

src/libraries/System.Private.CoreLib/src/Resources/Strings.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,9 @@
26032603
<data name="InvalidProgram_Default" xml:space="preserve">
26042604
<value>Common Language Runtime detected an invalid program.</value>
26052605
</data>
2606+
<data name="InvalidTimeZone_InvalidId" xml:space="preserve">
2607+
<value>The time zone ID '{0}' is invalid.</value>
2608+
</data>
26062609
<data name="InvalidTimeZone_InvalidFileData" xml:space="preserve">
26072610
<value>The time zone ID '{0}' was found on the local computer, but the file at '{1}' was corrupt.</value>
26082611
</data>
@@ -2627,6 +2630,9 @@
26272630
<data name="IO_NoFileTableInInMemoryAssemblies" xml:space="preserve">
26282631
<value>This assembly does not have a file table because it was loaded from memory.</value>
26292632
</data>
2633+
<data name="IO_UnseekableFile" xml:space="preserve">
2634+
<value>Unsupported unseekable file.</value>
2635+
</data>
26302636
<data name="IO_EOF_ReadBeyondEOF" xml:space="preserve">
26312637
<value>Unable to read beyond the end of the stream.</value>
26322638
</data>

src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.NonAndroid.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,61 @@ private static TimeZoneInfo GetLocalTimeZoneCore()
2424
return GetLocalTimeZoneFromTzFile();
2525
}
2626

27+
private static byte[] ReadAllBytesFromSeekableNonZeroSizeFile(string path, int maxFileSize)
28+
{
29+
using FileStream fs = File.OpenRead(path);
30+
if (!fs.CanSeek)
31+
{
32+
throw new IOException(SR.IO_UnseekableFile);
33+
}
34+
35+
if (fs.Length == 0 || fs.Length > maxFileSize)
36+
{
37+
throw new IOException(fs.Length == 0 ? SR.IO_InvalidReadLength : SR.IO_FileTooLong);
38+
}
39+
40+
byte[] bytes = new byte[fs.Length];
41+
fs.ReadExactly(bytes, 0, bytes.Length);
42+
return bytes;
43+
}
44+
45+
// Bitmap covering the ASCII range. The bits is set for the characters [a-z], [A-Z], [0-9], '/', '-', and '_'.
46+
private static byte[] asciiBitmap = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07 };
47+
private static bool IdContainsAnyDisallowedChars(string zoneId)
48+
{
49+
for (int i = 0; i < zoneId.Length; i++)
50+
{
51+
int c = zoneId[i];
52+
if (c > 0x7F)
53+
{
54+
return true;
55+
}
56+
int value = c >> 3;
57+
if ((asciiBitmap[value] & (ulong)(1UL << (c - (value << 3)))) == 0)
58+
{
59+
return true;
60+
}
61+
}
62+
return false;
63+
}
64+
2765
private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachineCore(string id, out TimeZoneInfo? value, out Exception? e)
2866
{
2967
value = null;
3068
e = null;
3169

70+
if (Path.IsPathRooted(id) || IdContainsAnyDisallowedChars(id))
71+
{
72+
e = new TimeZoneNotFoundException(SR.Format(SR.InvalidTimeZone_InvalidId, id));
73+
return TimeZoneInfoResult.TimeZoneNotFoundException;
74+
}
75+
3276
string timeZoneDirectory = GetTimeZoneDirectory();
3377
string timeZoneFilePath = Path.Combine(timeZoneDirectory, id);
3478
byte[] rawData;
3579
try
3680
{
37-
rawData = File.ReadAllBytes(timeZoneFilePath);
81+
rawData = ReadAllBytesFromSeekableNonZeroSizeFile(timeZoneFilePath, maxFileSize: 20 * 1024 * 1024 /* 20 MB */); // timezone files usually less than 1 MB.
3882
}
3983
catch (UnauthorizedAccessException ex)
4084
{
@@ -51,7 +95,7 @@ private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachineCore(string id,
5195
e = ex;
5296
return TimeZoneInfoResult.TimeZoneNotFoundException;
5397
}
54-
catch (IOException ex)
98+
catch (Exception ex) when (ex is IOException || ex is OutOfMemoryException)
5599
{
56100
e = new InvalidTimeZoneException(SR.Format(SR.InvalidTimeZone_InvalidFileData, id, timeZoneFilePath), ex);
57101
return TimeZoneInfoResult.InvalidTimeZoneException;

src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,11 @@ public static IEnumerable<object[]> ConvertTime_DateTimeOffset_InvalidDestinatio
20832083
yield return new object[] { s_strPacific + "\\Display" };
20842084
yield return new object[] { s_strPacific + "\n" }; // no trailing newline
20852085
yield return new object[] { new string('a', 100) }; // long string
2086+
yield return new object[] { "/dev/random" };
2087+
yield return new object[] { "Invalid Id" };
2088+
yield return new object[] { "Invalid/Invalid" };
2089+
yield return new object[] { $"./{s_strPacific}" };
2090+
yield return new object[] { $"{s_strPacific}/../{s_strPacific}" };
20862091
}
20872092

20882093
[Theory]

0 commit comments

Comments
 (0)