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

fix: Prevent null reference exceptions while serializing LoadedModuleWireModelCollection. (#2185) #2187

Merged
merged 3 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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 @@ -41,7 +41,7 @@ private static void WriteJsonImpl(JsonWriter jsonWriter, LoadedModuleWireModelCo
foreach (var item in loadedModule.Data)
{
jsonWriter.WritePropertyName(item.Key);
jsonWriter.WriteValue(item.Value.ToString());
jsonWriter.WriteValue(item.Value?.ToString() ?? " ");
nrcventura marked this conversation as resolved.
Show resolved Hide resolved
}

jsonWriter.WriteEndObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,7 @@ private static bool TryGetAssemblyName(Assembly assembly, out string assemblyNam
assemblyName = Path.GetFileName(assembly.Location);
}

if (string.IsNullOrWhiteSpace(assemblyName))
{
return false;
}

return true;
return !string.IsNullOrWhiteSpace(assemblyName);
}
catch
{
Expand All @@ -101,12 +96,7 @@ private static bool TryGetPublicKeyToken(AssemblyName assemblyDetails, out strin
try
{
publicKey = BitConverter.ToString(assemblyDetails.GetPublicKeyToken()).Replace("-", "");
if (string.IsNullOrWhiteSpace(publicKey))
{
return false;
}

return true;
return !string.IsNullOrWhiteSpace(publicKey);
}
catch
{
Expand Down Expand Up @@ -154,7 +144,7 @@ private static bool TryGetShaFileHashes(Assembly assembly, out string sha1FileHa
sha512.Dispose();
}

return true;
return !string.IsNullOrWhiteSpace(sha1FileHash) && !string.IsNullOrWhiteSpace(sha512FileHash);
}
catch
{
Expand All @@ -169,7 +159,7 @@ private static bool TryGetAssemblyHashCode(Assembly assembly, out string assembl
try
{
assemblyHashCode = assembly.GetHashCode().ToString();
return true;
return !string.IsNullOrWhiteSpace(assemblyHashCode);
}
catch
{
Expand All @@ -190,7 +180,7 @@ private static bool TryGetCompanyName(Assembly assembly, out string companyName)
}

companyName = ((AssemblyCompanyAttribute)attributes[0]).Company;
return true;
return !string.IsNullOrWhiteSpace(companyName);
}
catch
{
Expand All @@ -211,7 +201,7 @@ private static bool TryGetCopyright(Assembly assembly, out string copyright)
}

copyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
return true;
return !string.IsNullOrWhiteSpace(copyright);
}
catch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public void LoadedModuleWireModelCollectionIsJsonSerializable()
baseTestAssembly.SetAssemblyName = baseAssemblyName;
baseTestAssembly.SetDynamic = true; // false uses on disk assembly and this won'y have one.
baseTestAssembly.SetHashCode = BaseHashCode;
baseTestAssembly.SetLocation = BaseAssemblyPath;
baseTestAssembly.AddCustomAttribute(new AssemblyCompanyAttribute(BaseCompanyName));
baseTestAssembly.AddCustomAttribute(new AssemblyCopyrightAttribute(BaseCopyrightValue));

Expand All @@ -48,5 +47,30 @@ public void LoadedModuleWireModelCollectionIsJsonSerializable()
var serialized = JsonConvert.SerializeObject(new[] { loadedModules }, Formatting.None);
Assert.AreEqual(expected, serialized);
}

[Test]
public void LoadedModuleWireModelCollectionHandlesNulls()
{
var expected = @"[""Jars"",[[""MyTestAssembly"",""1.0.0"",{""namespace"":""MyTestAssembly"",""publicKeyToken"":""7075626C69636B6579746F6B656E"",""assemblyHashCode"":""42""}]]]";

var baseAssemblyName = new AssemblyName();
baseAssemblyName.Name = BaseAssemblyName;
baseAssemblyName.Version = new Version(BaseAssemblyVersion);
baseAssemblyName.SetPublicKeyToken(Encoding.ASCII.GetBytes(BasePublicKeyToken));

var baseTestAssembly = new TestAssembly();
baseTestAssembly.SetAssemblyName = baseAssemblyName;
baseTestAssembly.SetDynamic = true; // false uses on disk assembly and this won't have one.
baseTestAssembly.SetHashCode = BaseHashCode;
baseTestAssembly.AddCustomAttribute(new AssemblyCompanyAttribute(null));
baseTestAssembly.AddCustomAttribute(new AssemblyCopyrightAttribute(null));

var assemblies = new List<Assembly> { baseTestAssembly };

var loadedModules = LoadedModuleWireModelCollection.Build(assemblies);

var serialized = JsonConvert.SerializeObject(new[] { loadedModules }, Formatting.None);
Assert.AreEqual(expected, serialized);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using NewRelic.Agent.Core.Metrics;
using NewRelic.Collections;
using NUnit.Framework;
using Telerik.JustMock;
using static Google.Protobuf.Reflection.SourceCodeInfo.Types;

namespace NewRelic.Agent.Core.WireModels
{
[TestFixture]
public class LoadedModuleWireModelCollectionTests
{
private const string BaseAssemblyName = "MyTestAssembly";
private const string BaseAssemblyVersion = "1.0.0";
private const string BaseAssemblyPath = @"C:\path\to\assembly\MyTestAssembly.dll";
private const string BaseCompanyName = "MyCompany";
private const string BaseCopyrightValue = "Copyright 2008";
private const int BaseHashCode = 42;
private const string BasePublicKeyToken = "publickeytoken";
private const string BasePublicKey = "7075626C69636B6579746F6B656E";

private string BaseAssemblyVersion;
private string BaseCompanyName;
private string BaseCopyrightValue;
private int BaseHashCode;
private string BasePublicKeyToken;
private string BasePublicKey;

private AssemblyName _baseAssemblyName;
private TestAssembly _baseTestAssembly;

[SetUp]
public void SetUp()
{

BaseAssemblyVersion = "1.0.0";
BaseCompanyName = "MyCompany";
BaseCopyrightValue = "Copyright 2008";
BaseHashCode = 42;
BasePublicKeyToken = "publickeytoken";
BasePublicKey = "7075626C69636B6579746F6B656E";

_baseAssemblyName = new AssemblyName();
_baseAssemblyName.Name = BaseAssemblyName;
_baseAssemblyName.Version = new Version(BaseAssemblyVersion);
Expand All @@ -42,7 +44,6 @@ public void SetUp()
_baseTestAssembly.SetAssemblyName = _baseAssemblyName;
_baseTestAssembly.SetDynamic = true; // false uses on disk assembly and this won'y have one.
_baseTestAssembly.SetHashCode = BaseHashCode;
_baseTestAssembly.SetLocation = BaseAssemblyPath;
_baseTestAssembly.AddCustomAttribute(new AssemblyCompanyAttribute(BaseCompanyName));
_baseTestAssembly.AddCustomAttribute(new AssemblyCopyrightAttribute(BaseCopyrightValue));
}
Expand All @@ -60,10 +61,6 @@ [TearDown] public void TearDown()
public int TryGetAssemblyName_UsingCollectionCount(string assemblyName, bool isDynamic)
{
_baseAssemblyName.Name = assemblyName;
if (string.IsNullOrWhiteSpace(assemblyName))
{
_baseTestAssembly.SetLocation = null;
}

_baseTestAssembly.SetAssemblyName = _baseAssemblyName;
_baseTestAssembly.SetDynamic = isDynamic;
Expand Down Expand Up @@ -194,6 +191,35 @@ public void ErrorsHandled_GetCustomAttributes()
Assert.False(loadedModule.Data.ContainsKey("sha512Checksum"));
}

[Test]
public void ErrorsHandled_GetCustomAttributes_HandlesNulls()
{
_baseTestAssembly = new TestAssembly();
_baseTestAssembly.SetAssemblyName = _baseAssemblyName;
_baseTestAssembly.SetDynamic = true; // false uses on disk assembly and this won'y have one.
_baseTestAssembly.SetHashCode = BaseHashCode;
nr-ahemsath marked this conversation as resolved.
Show resolved Hide resolved


_baseTestAssembly.AddCustomAttribute(new AssemblyCompanyAttribute(null));
_baseTestAssembly.AddCustomAttribute(new AssemblyCopyrightAttribute(null));


var evilAssembly = new EvilTestAssembly(_baseTestAssembly);
evilAssembly.ItemToTest = "";

var assemblies = new List<Assembly>();
assemblies.Add(evilAssembly);

var loadedModules = LoadedModuleWireModelCollection.Build(assemblies);

Assert.AreEqual(1, loadedModules.LoadedModules.Count);

var loadedModule = loadedModules.LoadedModules[0];

Assert.False(loadedModule.Data.ContainsKey("Implementation-Vendor"));
Assert.False(loadedModule.Data.ContainsKey("copyright"));
}

[Test]
public void ErrorsHandled_PublickeyToken()
{
Expand Down Expand Up @@ -229,8 +255,6 @@ public class TestAssembly : Assembly

private int _hashCode;

private string _location;

private List<object> _customAttributes = new List<object>();

public AssemblyName SetAssemblyName
Expand Down Expand Up @@ -260,13 +284,6 @@ public override int GetHashCode()
return _hashCode;
}

public string SetLocation
{
set { _location = value; }
}

public override string Location => _location;

public void AddCustomAttribute(object attribute)
{
_customAttributes.Add(attribute);
Expand Down Expand Up @@ -332,19 +349,6 @@ public override int GetHashCode()
throw new Exception();
}

public override string Location
{
get
{
if (ItemToTest != "Location")
{
return _assembly.Location;
}

throw new Exception();
}
}

public override object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (ItemToTest != "GetCustomAttributes")
Expand Down
Loading