Skip to content

Avro serialization for floating point and integer types failing #522

@savannahsalverda

Description

@savannahsalverda

Using the following code:

  struct float_struct { float i; };
  struct double_struct { double i; };
  struct int_struct { int i; };
  struct long_struct { long i; };

  float_struct test_float_struct{ .i = 0.1 };
  double_struct test_double_struct{ .i = 0.1 };
  int_struct test_int_struct{ .i = 1 };
  long_struct test_long_struct{ .i = 1 };

  auto float_struct_serialized = rfl::avro::write( test_float_struct );
  auto double_struct_serialized = rfl::avro::write( test_double_struct );
  auto int_struct_serialized = rfl::avro::write( test_int_struct );
  auto long_struct_serialized = rfl::avro::write( test_long_struct );

The output in a debugger shows incorrect numbers of bytes and entirely null bytes:
(gdb) p float_struct_serialized
$5 = std::vector of length 4, capacity 4 = {0 '\000', 0 '\000', 0 '\000', 0 '\000'}
(gdb) p double_struct_serialized
$6 = std::vector of length 4, capacity 4 = {0 '\000', 0 '\000', 0 '\000', 0 '\000'}
(gdb) p int_struct_serialized
$7 = std::vector of length 1, capacity 1 = {0 '\000'}
(gdb) p long_struct_serialized
$8 = std::vector of length 1, capacity 1 = {0 '\000'}

This is using Ubuntu 22.04, gcc version 13.1.0, C++ standard 20, avro version 1.12.0, and reflect-cpp version 265b693 ( the current latest of main ), but I have also seen this with version 6f27b8a ( main as of 15 September ).

While debugging this, I stepped into the add_value_to_object function in the avro/Writer.hpp. In the float example above, this function shows the variable _var as 0.1, which is the correct value, but after the set_value call on line 166 the new_value.self pointer points to 0. Inside of the set_value function, avro_value_set_double gets called, which will always fail to set the value because the _val->iface->set_double is null, it is the _val->iface->set_float that has a non-null value. Changing the call to avro_value_set_float corrects the issue for floats, but there is still the issue that the serialization of the double_struct is only 4 bytes ( although after this change the 4 bytes are non-zero ). After taking a quick look at the int_struct and long_struct serialization it appears that the issue there is similar.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions