-
-
Notifications
You must be signed in to change notification settings - Fork 939
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Limit TimeSpan timeouts to Int32 MaxValue (#1321)
* Added guard clauses to various timeouts to ensure they don't exceed an Int32 in milliseconds. * Fixed guard clauses. * Updated build tags. * Added guard clauses to various timeouts to ensure they don't exceed an Int32 in milliseconds. * Fixed tests. * Added additional tests. * Replaced NoWarn with .editorconfig setting * Fixed references to parameter names.
- Loading branch information
Showing
18 changed files
with
328 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System; | ||
|
||
namespace Renci.SshNet.Common | ||
{ | ||
/// <summary> | ||
/// Provides extension methods for <see cref="TimeSpan"/>. | ||
/// </summary> | ||
internal static class TimeSpanExtensions | ||
{ | ||
private const string OutOfRangeTimeoutMessage = | ||
$"The timeout must represent a value between -1 and Int32.MaxValue milliseconds, inclusive."; | ||
|
||
/// <summary> | ||
/// Returns the specified <paramref name="timeSpan"/> as a valid timeout in milliseconds. | ||
/// </summary> | ||
/// <param name="timeSpan">The <see cref="TimeSpan"/> to ensure validity.</param> | ||
/// <param name="callerMemberName">The name of the calling member.</param> | ||
/// <exception cref="ArgumentOutOfRangeException"> | ||
/// Thrown when <paramref name="timeSpan"/> does not represent a value between -1 and <see cref="int.MaxValue"/>, inclusive. | ||
/// </exception> | ||
public static int AsTimeout(this TimeSpan timeSpan, string callerMemberName) | ||
{ | ||
var timeoutInMilliseconds = timeSpan.TotalMilliseconds; | ||
return timeoutInMilliseconds is < -1d or > int.MaxValue | ||
? throw new ArgumentOutOfRangeException(callerMemberName, OutOfRangeTimeoutMessage) | ||
: (int) timeoutInMilliseconds; | ||
} | ||
|
||
/// <summary> | ||
/// Ensures that the specified <paramref name="timeSpan"/> represents a valid timeout in milliseconds. | ||
/// </summary> | ||
/// <param name="timeSpan">The <see cref="TimeSpan"/> to ensure validity.</param> | ||
/// <param name="callerMemberName">The name of the calling member.</param> | ||
/// <exception cref="ArgumentOutOfRangeException"> | ||
/// Thrown when <paramref name="timeSpan"/> does not represent a value between -1 and <see cref="int.MaxValue"/>, inclusive. | ||
/// </exception> | ||
public static void EnsureValidTimeout(this TimeSpan timeSpan, string callerMemberName) | ||
{ | ||
var timeoutInMilliseconds = timeSpan.TotalMilliseconds; | ||
if (timeoutInMilliseconds is < -1d or > int.MaxValue) | ||
{ | ||
throw new ArgumentOutOfRangeException(callerMemberName, OutOfRangeTimeoutMessage); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
test/Renci.SshNet.Tests/Classes/Common/TimeSpanExtensionsTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
using System; | ||
|
||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
|
||
using Renci.SshNet.Common; | ||
using Renci.SshNet.Tests.Common; | ||
|
||
namespace Renci.SshNet.Tests.Classes.Common | ||
{ | ||
[TestClass] | ||
public class TimeSpanExtensionsTest | ||
{ | ||
[TestMethod] | ||
public void AsTimeout_ValidTimeSpan_ReturnsExpectedMilliseconds() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(10); | ||
|
||
var timeout = timeSpan.AsTimeout("TestMethodName"); | ||
|
||
Assert.AreEqual(10000, timeout); | ||
} | ||
|
||
[TestMethod] | ||
[ExpectedException(typeof(ArgumentOutOfRangeException))] | ||
public void AsTimeout_NegativeTimeSpan_ThrowsArgumentOutOfRangeException() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(-1); | ||
|
||
timeSpan.AsTimeout("TestMethodName"); | ||
} | ||
|
||
[TestMethod] | ||
[ExpectedException(typeof(ArgumentOutOfRangeException))] | ||
public void AsTimeout_TimeSpanExceedingMaxValue_ThrowsArgumentOutOfRangeException() | ||
{ | ||
var timeSpan = TimeSpan.FromMilliseconds((double) int.MaxValue + 1); | ||
|
||
timeSpan.AsTimeout("TestMethodName"); | ||
} | ||
|
||
[TestMethod] | ||
public void AsTimeout_ArgumentOutOfRangeException_HasCorrectInformation() | ||
{ | ||
|
||
try | ||
{ | ||
var timeSpan = TimeSpan.FromMilliseconds((double) int.MaxValue + 1); | ||
|
||
timeSpan.AsTimeout("TestMethodName"); | ||
} | ||
catch (ArgumentOutOfRangeException ex) | ||
{ | ||
Assert.IsNull(ex.InnerException); | ||
ArgumentExceptionAssert.MessageEquals("The timeout must represent a value between -1 and Int32.MaxValue milliseconds, inclusive.", ex); | ||
Assert.AreEqual("TestMethodName", ex.ParamName); | ||
} | ||
} | ||
|
||
[TestMethod] | ||
public void EnsureValidTimeout_ValidTimeSpan_DoesNotThrow() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(5); | ||
|
||
timeSpan.EnsureValidTimeout("TestMethodName"); | ||
} | ||
|
||
[TestMethod] | ||
[ExpectedException(typeof(ArgumentOutOfRangeException))] | ||
public void EnsureValidTimeout_NegativeTimeSpan_ThrowsArgumentOutOfRangeException() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(-1); | ||
|
||
timeSpan.EnsureValidTimeout("TestMethodName"); | ||
} | ||
|
||
[TestMethod] | ||
[ExpectedException(typeof(ArgumentOutOfRangeException))] | ||
public void EnsureValidTimeout_TimeSpanExceedingMaxValue_ThrowsArgumentOutOfRangeException() | ||
{ | ||
var timeSpan = TimeSpan.FromMilliseconds((double) int.MaxValue + 1); | ||
|
||
timeSpan.EnsureValidTimeout("TestMethodName"); | ||
} | ||
|
||
[TestMethod] | ||
public void EnsureValidTimeout_ArgumentOutOfRangeException_HasCorrectInformation() | ||
{ | ||
|
||
try | ||
{ | ||
var timeSpan = TimeSpan.FromMilliseconds((double) int.MaxValue + 1); | ||
|
||
timeSpan.EnsureValidTimeout("TestMethodName"); | ||
} | ||
catch (ArgumentOutOfRangeException ex) | ||
{ | ||
Assert.IsNull(ex.InnerException); | ||
ArgumentExceptionAssert.MessageEquals("The timeout must represent a value between -1 and Int32.MaxValue milliseconds, inclusive.", ex); | ||
Assert.AreEqual("TestMethodName", ex.ParamName); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.