-
Notifications
You must be signed in to change notification settings - Fork 832
Description
Using base.XXX to call a base method causes a BadImageFormatException to be raised.
EDIT: it looks like F# allowing me to call an abstract method, as the base class is abstract. This, I believe, should not be allowed and JIT therefore throws a BadImageFormatException. If you try to write code in F# with an AbstractClass and a derived class, you'd receive a normal compile-time error.
Repro steps
The following code (requires Giraffe and FsUnit to run the test) throws a BadImageFormatException
namespace Test
open Giraffe
open Xunit
open FsUnit.Xunit
open System.Text.Json
open System.Text.Json.Serialization
type StringTrimJsonSerializer(o: JsonSerializerOptions) =
inherit JsonConverter<string>()
override this.Read(reader, _, _) =
match reader.TokenType with
| JsonTokenType.String -> reader.GetString().Trim()
| _ -> JsonException("Type is not a string") |> raise
/// This causes a BadImageFormatException
override this.Write(writer, objectToWrite, options) = base.Write(writer, objectToWrite, options)
module SerializationTests =
type SomeType = { Amount: decimal; Currency: string }
let serialize item =
let options = SystemTextJson.Serializer.DefaultOptions
StringTrimJsonSerializer options |> options.Converters.Add
JsonSerializer.Serialize(item, options)
let deserialize<'T> (stringValue: string) =
let options = SystemTextJson.Serializer.DefaultOptions
StringTrimJsonSerializer options |> options.Converters.Add
JsonSerializer.Deserialize<'T>(stringValue, options)
[<Fact>]
let ``Roundtip type should trim currency whitespace`` () =
{ Amount = 42.99M; Currency = " USD " }
|> serialize
|> deserialize<SomeType>
|> should equal { Amount = 42.99M; Currency = "USD" }
Expected behavior
Should call the base method or give compile error if such method doesn't exist.
Actual behavior
Throws:
BadImageFormatException : Bad IL format.
Known workarounds
Don't use base in a derived method.
Related information
On dotnet 6, using System.Text.Json serialization BCL classes, Windows 10/11.
EDIT, the IL of the offending code looks as follows (Release build):
.method public hidebysig virtual
instance void Write (
class [System.Text.Json]System.Text.Json.Utf8JsonWriter writer,
string objectToWrite,
class [System.Text.Json]System.Text.Json.JsonSerializerOptions options
) cil managed
{
// Method begins at RVA 0x316c
// Header size: 1
// Code size: 10 (0xa)
.maxstack 8
// base.Write(writer, objectToWrite, options);
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: ldarg.3
IL_0004: call instance void class [System.Text.Json]System.Text.Json.Serialization.JsonConverter`1<string>::Write(class [System.Text.Json]System.Text.Json.Utf8JsonWriter, !0, class [System.Text.Json]System.Text.Json.JsonSerializerOptions)
// }
IL_0009: ret
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Status