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 10, 2022
1 parent 4ca53d2 commit e8910fa
Showing 2 changed files with 54 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/Elastic.CommonSchema/Serialization/JsonConfiguration.cs
Original file line number Diff line number Diff line change
@@ -18,14 +18,35 @@ 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.Type>(), // Cannot transfer types over the wire
new EcsJsonStringConverter<System.Collections.IEqualityComparer>(), // Cannot transfer Dictionary-Comparer 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());
}
}
}
}
31 changes: 31 additions & 0 deletions tests/Elastic.CommonSchema.NLog.Tests/MessageTests.cs
Original file line number Diff line number Diff line change
@@ -49,6 +49,37 @@ 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());
}

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

0 comments on commit e8910fa

Please sign in to comment.