Skip to content

Commit

Permalink
More-tolerant mscorlib type references (#4829)
Browse files Browse the repository at this point in the history
Fixes #4773 by treating string and MemoryStream types as a prefix match on the mscorlib identity,
hoping to more closely match `Type.GetType`'s behavior.
  • Loading branch information
rainersigwald authored Oct 22, 2019
1 parent 62a87ea commit 321ea29
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
33 changes: 33 additions & 0 deletions src/Tasks.UnitTests/ResourceHandling/MSBuildResXReader_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,39 @@ public void ResXFileRefToBitmap()
resource.TypeAssemblyQualifiedName.ShouldBe("System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
}

[Theory]
[InlineData("System.IO.MemoryStream, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
[InlineData("System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public void ResXFileRefToMemoryStream(string typeNameInResx)
{
using var env = TestEnvironment.Create(_output);

var baseDir = env.CreateFolder(createFolder: true);
var resourceHandlingFolder = baseDir.CreateDirectory("ResourceHandling");

var linkedTextFile = resourceHandlingFolder.CreateFile("FileToBeIncluded.txt");

File.WriteAllText(linkedTextFile.Path,
"Test data");

var resources = MSBuildResXReader.GetResourcesFromString(
ResXHelper.SurroundWithBoilerplate(
$@" <data name='Image1' type='System.Resources.ResXFileRef, System.Windows.Forms'>
<value>{linkedTextFile.Path};{typeNameInResx}</value>
</data>
"));

var resource = resources.ShouldHaveSingleItem()
.ShouldBeOfType<LiveObjectResource>();
resource.Name.ShouldBe("Image1");

byte[] bytes = new byte[4];
resource.Value
.ShouldBeOfType<MemoryStream>()
.Read(bytes, 0, 4);
bytes.ShouldBe(new byte[] { 84, 101, 115, 116 }, "Expected the bytes of 'Test' to start the stream");
}

[Fact]
public void AssemblyElementWithNoAliasInfersSimpleName()
{
Expand Down
9 changes: 4 additions & 5 deletions src/Tasks/ResourceHandling/MSBuildResXReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ private static void ParseAssemblyAlias(Dictionary<string,string> aliases, XEleme
private const string ByteArraySerializedObjectMimeType = "application/x-microsoft.net.object.bytearray.base64";
private const string ResMimeType = "text/microsoft-resx";

private const string StringTypeName20 = "System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
private const string StringTypeNamePrefix = "System.String, mscorlib,";
private const string StringTypeName40 = "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
private const string MemoryStreamTypeNameDesktopFramework = "System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
private const string MemoryStreamTypeNamePrefix = "System.IO.MemoryStream, mscorlib,";

private static string GetFullTypeNameFromAlias(string aliasedTypeName, Dictionary<string, string> aliases)
{
Expand Down Expand Up @@ -275,13 +275,12 @@ private static bool IsByteArray(string fileRefType)

internal static bool IsString(string fileRefType)
{
return fileRefType.Equals(StringTypeName40, StringComparison.Ordinal) ||
fileRefType.Equals(StringTypeName20, StringComparison.Ordinal);
return fileRefType.StartsWith(StringTypeNamePrefix, StringComparison.Ordinal);
}

internal static bool IsMemoryStream(string fileRefType)
{
return fileRefType.Equals(MemoryStreamTypeNameDesktopFramework, StringComparison.Ordinal);
return fileRefType.StartsWith(MemoryStreamTypeNamePrefix, StringComparison.Ordinal);
}

/// <summary>
Expand Down

0 comments on commit 321ea29

Please sign in to comment.