Skip to content

Commit

Permalink
EcsJsonConfiguration - With converters to protect against bad types
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed Sep 11, 2022
1 parent 4ca53d2 commit b7c4a96
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Elastic.CommonSchema/Serialization/JsonConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,33 @@ public static class EcsJsonConfiguration
PropertyNamingPolicy = new SnakeCaseJsonNamingPolicy(),
Converters =
{
new EcsDocumentJsonConverterFactory()
new EcsDocumentJsonConverterFactory(),
new EcsJsonStringConverter<System.Reflection.Assembly>(), // Cannot transfer assembly-objects over the wire
new EcsJsonStringConverter<System.Reflection.Module>(), // Cannot transfer module-objects over the wire
new EcsJsonStringConverter<System.Reflection.MemberInfo>(), // Cannot transfer method-addresses over the wire
new EcsJsonStringConverter<System.Delegate>(), // Cannot transfer methods over the wire
new EcsJsonStringConverter<System.IO.Stream>(), // Stream-properties often throws exceptions
},

};

internal static readonly JsonConverter<DateTimeOffset> DateTimeOffsetConverter =
(JsonConverter<DateTimeOffset>)SerializerOptions.GetConverter(typeof(DateTimeOffset));

public static readonly EcsDocumentJsonConverter DefaultEcsDocumentJsonConverter = new();

private sealed class EcsJsonStringConverter<T> : JsonConverter<T>
{
public override bool CanConvert(Type typeToConvert) => typeof(T).IsAssignableFrom(typeToConvert);

public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => default;

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
if (value is null)
writer.WriteNullValue();
else
writer.WriteStringValue(value.ToString());
}
}
}
}
35 changes: 35 additions & 0 deletions tests/Elastic.CommonSchema.NLog.Tests/MessageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,41 @@ public void SeesMessageWithProp() => TestLogger((logger, getLogEvents) =>
y.Should().HaveValue().And.Be(2.2);
});

[Fact]
public void SeesMessageWithEvilProp() => TestLogger((logger, getLogEvents) =>
{
logger.Info("Info {EvilValue}", new BadObject());

var logEvents = getLogEvents();
logEvents.Should().HaveCount(1);

var ecsEvents = ToEcsEvents(logEvents);

var (_, info) = ecsEvents.First();
info.Message.Should().Be("Info Elastic.CommonSchema.NLog.Tests.MessageTests+BadObject");
info.Metadata.Should().ContainKey("EvilValue");

var x = info.Metadata["EvilValue"] as System.Collections.Generic.Dictionary<string, object>;
x.Should().NotBeNull().And.NotBeEmpty();
});

class BadObject
{
// public IEnumerable<object> Recursive => new List<object>(new[] { "Hello", (object)this })

// public string EvilProperty => throw new NotSupportedException()

public System.Type TypeProperty { get; } = typeof(BadObject);

public System.Reflection.MethodInfo MethodInfoProperty { get; } = typeof(BadObject).GetProperty(nameof(MethodInfoProperty)).GetMethod;

public System.Action DelegateProperty { get; } = new System.Action(() => throw new NotSupportedException());

public System.Collections.IEqualityComparer ComparerProperty { get; } = StringComparer.OrdinalIgnoreCase;

public System.IFormatProvider CultureProperty { get; } = System.Globalization.CultureInfo.InvariantCulture;
}

[Fact]
public void SeesMessageWithException() => TestLogger((logger, getLogEvents) =>
{
Expand Down

0 comments on commit b7c4a96

Please sign in to comment.