Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging internal commits for release/6.0 #83404

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
54bb24f
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
c2c7afa
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
d411de8
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
3961581
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
3859f81
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
75e3eac
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
3d2923d
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
6275102
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
7f24ff7
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
b100014
Merge in 'release/6.0' changes
dotnet-bot Feb 8, 2023
1b85704
Merge in 'release/6.0' changes
dotnet-bot Feb 9, 2023
8c4e317
Merge in 'release/6.0' changes
dotnet-bot Feb 9, 2023
ca4d7bb
Merge in 'release/6.0' changes
dotnet-bot Feb 9, 2023
47b46c3
Merge in 'release/6.0' changes
dotnet-bot Feb 10, 2023
e0c5bf0
Merge in 'release/6.0' changes
dotnet-bot Feb 10, 2023
d0004a3
Merged PR 28980: Fix TimeZone when reading invalid TZ files
tarekgh Feb 10, 2023
3a8c500
Merge in 'release/6.0' changes
dotnet-bot Feb 10, 2023
d4a7595
Merge in 'release/6.0' changes
dotnet-bot Feb 11, 2023
4ef7e67
Merge in 'release/6.0' changes
dotnet-bot Feb 13, 2023
5789ff7
Merge in 'release/6.0' changes
dotnet-bot Feb 13, 2023
9b4f0e3
Merge in 'release/6.0' changes
dotnet-bot Feb 14, 2023
0aa8845
Merge in 'release/6.0' changes
dotnet-bot Feb 14, 2023
22da7ee
Merge in 'release/6.0' changes
dotnet-bot Feb 15, 2023
5edef4b
Merge in 'release/6.0' changes
dotnet-bot Feb 16, 2023
adc4201
Merge commit '5edef4b20babd4c3ddac7460e536f86fd0f2d724' into internal…
vseanreesermsft Mar 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2617,6 +2617,9 @@
<data name="InvalidProgram_Default" xml:space="preserve">
<value>Common Language Runtime detected an invalid program.</value>
</data>
<data name="InvalidTimeZone_InvalidId" xml:space="preserve">
<value>The time zone ID '{0}' is invalid.</value>
</data>
<data name="InvalidTimeZone_InvalidFileData" xml:space="preserve">
<value>The time zone ID '{0}' was found on the local computer, but the file at '{1}' was corrupt.</value>
</data>
Expand All @@ -2641,6 +2644,9 @@
<data name="IO_NoFileTableInInMemoryAssemblies" xml:space="preserve">
<value>This assembly does not have a file table because it was loaded from memory.</value>
</data>
<data name="IO_UnseekableFile" xml:space="preserve">
<value>Unsupported unseekable file.</value>
</data>
<data name="IO_EOF_ReadBeyondEOF" xml:space="preserve">
<value>Unable to read beyond the end of the stream.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,83 @@ private static TimeZoneInfo GetLocalTimeZoneCore()
return GetLocalTimeZoneFromTzFile();
}

internal static byte[] ReadAllBytesFromSeekableNonZeroSizeFile(string path, int maxFileSize)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1, FileOptions.SequentialScan))
{
if (!fs.CanSeek)
{
throw new IOException(SR.IO_UnseekableFile);
}

long fileLength = fs.Length;
if (fileLength > maxFileSize)
{
throw new IOException(SR.IO_FileTooLong);
}

if (fileLength == 0)
{
throw new IOException(SR.IO_InvalidReadLength);
}

int index = 0;
int count = (int)fileLength;
byte[] bytes = new byte[count];
while (count > 0)
{
int n = fs.Read(bytes, index, count);
if (n == 0)
{
ThrowHelper.ThrowEndOfFileException();
}
index += n;
count -= n;
}
return bytes;
}
}

// Bitmap covering the ASCII range. The bits is set for the characters [a-z], [A-Z], [0-9], '/', '-', and '_'.
private static byte[] asciiBitmap = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07 };

private static bool IdContainsAnyDisallowedChars(string zoneId)
{
for (int i = 0; i < zoneId.Length; i++)
{
int c = zoneId[i];
if (c > 0x7F)
{
return true;
}

int value = c >> 3;
if ((asciiBitmap[value] & (ulong)(1UL << (c - (value << 3)))) == 0)
{
return true;
}
}

return false;
}

private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachineCore(string id, out TimeZoneInfo? value, out Exception? e)
{
value = null;
e = null;

if (Path.IsPathRooted(id) || IdContainsAnyDisallowedChars(id))
{
e = new TimeZoneNotFoundException(SR.Format(SR.InvalidTimeZone_InvalidId, id));
return TimeZoneInfoResult.TimeZoneNotFoundException;
}

string timeZoneDirectory = GetTimeZoneDirectory();
string timeZoneFilePath = Path.Combine(timeZoneDirectory, id);
byte[] rawData;
try
{
rawData = File.ReadAllBytes(timeZoneFilePath);
rawData = ReadAllBytesFromSeekableNonZeroSizeFile(timeZoneFilePath, maxFileSize: 20 * 1024 * 1024 /* 20 MB */); // timezone files usually less than 1 MB.
}
catch (UnauthorizedAccessException ex)
{
Expand All @@ -51,7 +117,7 @@ private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachineCore(string id,
e = ex;
return TimeZoneInfoResult.TimeZoneNotFoundException;
}
catch (IOException ex)
catch (Exception ex) when (ex is IOException || ex is OutOfMemoryException)
{
e = new InvalidTimeZoneException(SR.Format(SR.InvalidTimeZone_InvalidFileData, id, timeZoneFilePath), ex);
return TimeZoneInfoResult.InvalidTimeZoneException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2091,14 +2091,20 @@ public static IEnumerable<object[]> ConvertTime_DateTimeOffset_InvalidDestinatio
yield return new object[] { s_strPacific + "\\Display" };
yield return new object[] { s_strPacific + "\n" }; // no trailing newline
yield return new object[] { new string('a', 100) }; // long string
yield return new object[] { "/dev/random" };
yield return new object[] { "Invalid Id" };
yield return new object[] { "Invalid/Invalid" };
yield return new object[] { $"./{s_strPacific}" };
yield return new object[] { $"{s_strPacific}/../{s_strPacific}" };
}

[Theory]
[MemberData(nameof(ConvertTime_DateTimeOffset_InvalidDestination_TimeZoneNotFoundException_MemberData))]
public static void ConvertTime_DateTimeOffset_InvalidDestination_TimeZoneNotFoundException(string destinationId)
{
DateTimeOffset time1 = new DateTimeOffset(2006, 5, 12, 0, 0, 0, TimeSpan.Zero);
VerifyConvertException<TimeZoneNotFoundException>(time1, destinationId);
Exception ex = Record.Exception(() => TimeZoneInfo.ConvertTime(time1, TimeZoneInfo.FindSystemTimeZoneById(destinationId)));
Assert.True(ex is InvalidTimeZoneException || ex is TimeZoneNotFoundException);
}

[Fact]
Expand Down