Skip to content

Commit

Permalink
Added TestBase class, fixed code analysis warnings.
Browse files Browse the repository at this point in the history
  • Loading branch information
yallie committed Apr 25, 2018
1 parent 73bfede commit fe21e57
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 119 deletions.
31 changes: 20 additions & 11 deletions SafeDeserializationHelpers.Tests/DelegateValidatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,59 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class DelegateValidatorTests
public class DelegateValidatorTests : TestBase
{
[TestMethod]
public void NullDelegateIsValid()
{
// Assert.DoesNotThrow
DelegateValidator.Default.ValidateDelegate(null);
Assert_DoesNotThrow(() =>
DelegateValidator.Default.ValidateDelegate(null));
}

[TestMethod]
public void DelegateIsValidUnlessBlacklisted()
{
DelegateValidator.Default.ValidateDelegate(new Action<int>(x => { }));
Assert_DoesNotThrow(() =>
DelegateValidator.Default.ValidateDelegate(new Action<int>(x => { })));
}

[TestMethod, ExpectedException(typeof(UnsafeDeserializationException))]
[TestMethod]
public void SystemDiagnosticsDelegatesAreNotValid()
{
var del = new Func<string, string, Process>(Process.Start);
DelegateValidator.Default.ValidateDelegate(del);

Assert_Throws<UnsafeDeserializationException>(() =>
DelegateValidator.Default.ValidateDelegate(del));
}

[TestMethod, ExpectedException(typeof(UnsafeDeserializationException))]
[TestMethod]
public void SystemIODelegatesAreNotValid()
{
var del = new Action<string>(File.Delete);
DelegateValidator.Default.ValidateDelegate(del);

Assert_Throws<UnsafeDeserializationException>(() =>
DelegateValidator.Default.ValidateDelegate(del));
}

[TestMethod]
public void MulticastDelegatesAreValidated()
{
var del = new Func<string, string, Process>((a, b) => null);
del = Delegate.Combine(del, del, del) as Func<string, string, Process>;
DelegateValidator.Default.ValidateDelegate(del);

Assert_DoesNotThrow(() =>
DelegateValidator.Default.ValidateDelegate(del));
}

[TestMethod, ExpectedException(typeof(UnsafeDeserializationException))]
[TestMethod]
public void MulticastDelegatesWithSystemDiagnosticsMethodsAreNotValid()
{
var del = new Func<string, string, Process>((a, b) => null);
var start = new Func<string, string, Process>(Process.Start);
del = Delegate.Combine(del, del, start, del, del) as Func<string, string, Process>;
DelegateValidator.Default.ValidateDelegate(del);

Assert_Throws<UnsafeDeserializationException>(() =>
DelegateValidator.Default.ValidateDelegate(del));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand All @@ -46,6 +47,7 @@
<Compile Include="DelegateValidatorTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SafeSerializationBinderTests.cs" />
<Compile Include="TestBase.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeDeserializationHelpers\SafeDeserializationHelpers.csproj">
Expand Down
124 changes: 29 additions & 95 deletions SafeDeserializationHelpers.Tests/SafeSerializationBinderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,102 +4,13 @@
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace SafeDeserializationHelpers.Tests
{
[TestClass]
public class SafeSerializationBinderTests
public class SafeSerializationBinderTests : TestBase
{
private void Roundtrip(object graph, bool useBinder)
{
var data = default(byte[]);
var fmt = new BinaryFormatter();
using (var stream = new MemoryStream())
{
fmt.Serialize(stream, graph);
data = stream.ToArray();
}

if (useBinder)
{
fmt.Binder = new SafeSerializationBinder(fmt.Binder);
}

using (var stream = new MemoryStream(data))
{
var deserialized = fmt.Deserialize(stream);
var msg = $"Deserialized data doesn't match when {(useBinder ? string.Empty : "not ")}using binder.";
AssertAreEqual(graph, deserialized, msg);
}
}

private void AssertAreEqual(object expected, object actual, string msg)
{
if (expected is Delegate del1 && actual is Delegate del2)
{
AssertAreEqual(del1.Target, del2.Target, msg);
AssertAreEqual(del1.Method, del2.Method, msg);
return;
}

if (expected is string s1 && actual is string s2)
{
// avoid comparing strings as IEnumerables
Assert.AreEqual(s1, s2, msg);
return;
}

if (expected is IEnumerable enum1 && actual is IEnumerable enum2)
{
Assert.AreEqual(enum1.OfType<object>().Count(), enum2.OfType<object>().Count(), msg);
foreach (var item in enum1.OfType<object>().Zip(enum2.OfType<object>(), (e1, e2) => (e1, e2)))
{
AssertAreEqual(item.e1, item.e2, msg);
}

return;
}

if (expected is IDictionary dic1 && actual is IDictionary dic2)
{
Assert.AreEqual(dic1.Count, dic2.Count, msg);
foreach (var item in dic1.OfType<object>().Zip(dic2.OfType<object>(), (e1, e2) => (e1, e2)))
{
AssertAreEqual(item.e1, item.e2, msg);
}

return;
}

if (expected is DataTable dt1 && actual is DataTable dt2)
{
AssertAreEqual(dt1.TableName, dt2.TableName, msg);
AssertAreEqual(dt1.Columns, dt2.Columns, msg);
AssertAreEqual(dt1.Rows, dt2.Rows, msg);
return;
}

if (expected is DataColumn dc1 && actual is DataColumn dc2)
{
AssertAreEqual(dc1.ColumnName, dc2.ColumnName, msg);
AssertAreEqual(dc1.DataType, dc2.DataType, msg);
return;
}

if (expected is DataRow dr1 && actual is DataRow dr2)
{
AssertAreEqual(dr1.ItemArray, dr2.ItemArray, msg);
return;
}

Assert.AreEqual(expected, actual, msg);
}

[Serializable]
public class PublicSerializable
{
Expand Down Expand Up @@ -141,10 +52,14 @@ public void SafeSerializationBinderDoesntBreakNormalClasses()
row["Name"] = "432";
dt.Rows.Add(row);

// data sets
var ds = new DataSet("TestData");
ds.Tables.Add(dt);

// scalar values, collections and dictionaries
var samples = new object[]
{
1, "Test", func, action, dt,
1, "Test", func, action, dt, ds,
new List<string> { "abc", "def" },
new Dictionary<int, char> { { 1, 'a' }, { 2, 'b'} },
new Hashtable { { "Hello", "World" } },
Expand All @@ -164,13 +79,32 @@ public void SafeSerializationBinderDoesntBreakNormalClasses()
[TestMethod]
public void OrdinaryBinaryFormatterDoesntBreakOnProcessStartDelegate()
{
Roundtrip(new Func<string, string, Process>(Process.Start), false);
Assert_DoesNotThrow(() =>
Roundtrip(new Func<string, string, Process>(Process.Start), false));
}

[TestMethod]
public void SafeSerializationBinderBreaksOnProcessStartDelegate1()
{
Assert_Throws<UnsafeDeserializationException>(() =>
Roundtrip(new Func<string, string, Process>(Process.Start), true));
}

[TestMethod, ExpectedException(typeof(UnsafeDeserializationException))]
public void SafeSerializationBinderBreaksOnProcessStartDelegate()
[TestMethod]
public void SafeSerializationBinderBreaksOnProcessStartDelegate2()
{
// add Process.Start somewhere to the chain of the delegates
var d = new Func<string, string, Process>((s1, s2) => null);
var e = new Func<string, string, Process>(Process.Start);
var f = Delegate.Combine(d, d, e, d, d);

Assert_Throws<UnsafeDeserializationException>(() => Roundtrip(f, true));
}

[TestMethod]
public void OrdinaryBinaryFormatterDoesntBreakOnFileDeleteDelegate()
{
Roundtrip(new Func<string, string, Process>(Process.Start), true);
Assert_DoesNotThrow(() => Roundtrip(new Action<string>(File.Delete), false));
}
}
}
Loading

0 comments on commit fe21e57

Please sign in to comment.