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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions