Skip to content

Commit c1f019d

Browse files
committed
Added test demonstrating behavior on TypeLoadException
1 parent d9df235 commit c1f019d

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/DataProtection/DataProtection/src/XmlEncryption/XmlEncryptionExtensions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ namespace Microsoft.AspNetCore.DataProtection.XmlEncryption;
1616

1717
internal static unsafe class XmlEncryptionExtensions
1818
{
19+
// Used for testing edge case assembly loading errors
20+
internal static Func<string, Type> _getType = name => Type.GetType(name, throwOnError: false);
21+
1922
public static XElement DecryptElement(this XElement element, IActivator activator)
2023
{
2124
// If no decryption necessary, return original element.
@@ -73,7 +76,7 @@ private static IXmlDecryptor CreateDecryptor(IActivator activator, string decryp
7376
var resolvedTypeName = TypeForwardingActivator.TryForwardTypeName(decryptorTypeName, out var forwardedTypeName)
7477
? forwardedTypeName
7578
: decryptorTypeName;
76-
var type = Type.GetType(resolvedTypeName, throwOnError: false);
79+
var type = _getType(resolvedTypeName);
7780

7881
if (type == typeof(DpapiNGXmlDecryptor))
7982
{

src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/XmlEncryption/XmlEncryptionExtensionsTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,37 @@ public void DecryptElement_RootNodeRequiresDecryption_Success()
4949
XmlAssert.Equal("<newNode />", retVal);
5050
}
5151

52+
[Fact]
53+
public void DecryptElement_MissingDecryptorType_Success()
54+
{
55+
// Arrange
56+
// We want to simulate an error loading the specified decryptor type, i.e.
57+
// Could not load file or assembly 'Azure.Extensions.AspNetCore.DataProtection.Keys,
58+
// Version=1.2.2.0, Culture=neutral, PublicKeyToken=92742159e12e44c8' or one of its dependencies.
59+
XmlEncryptionExtensions._getType = _ => throw new TypeLoadException();
60+
61+
var decryptorTypeName = typeof(MyXmlDecryptor).AssemblyQualifiedName;
62+
63+
var original = XElement.Parse(@$"
64+
<x:encryptedSecret decryptorType='{decryptorTypeName}' xmlns:x='http://schemas.asp.net/2015/03/dataProtection'>
65+
<node />
66+
</x:encryptedSecret>");
67+
68+
var mockActivator = new Mock<IActivator>();
69+
mockActivator.ReturnDecryptedElementGivenDecryptorTypeNameAndInput(decryptorTypeName, "<node />", "<newNode />");
70+
71+
var serviceCollection = new ServiceCollection();
72+
serviceCollection.AddSingleton<IActivator>(mockActivator.Object);
73+
var services = serviceCollection.BuildServiceProvider();
74+
var activator = services.GetActivator();
75+
76+
// Act
77+
var retVal = original.DecryptElement(activator);
78+
79+
// Assert
80+
XmlAssert.Equal("<newNode />", retVal);
81+
}
82+
5283
[Fact]
5384
public void DecryptElement_MultipleNodesRequireDecryption_AvoidsRecursion_Success()
5485
{

0 commit comments

Comments
 (0)