Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add missing float/double bounds check #128

Merged
merged 5 commits into from
Jun 15, 2021

Conversation

squizz617
Copy link
Contributor

@squizz617 squizz617 commented Mar 9, 2021

This pull request fixes the issue described below:
Floating-point types of different precision (float32/float64 in ROS, float/double in rclcpp and DDS), are not handled properly in rclpy (and corresponding rosidl_python intefaces), as the type checks rely solely on Python's built-in float type.

For example, when publishing a double-sized floating point value (e.g., 3.5e+100) as float32 type, the data goes through various type checks at different places:

  1. if type(3.5e+100) is float in rosidl_runtime_py/set_message.py,
  2. assert(isinstance(3.5e+100, float)) in the msg setter code automatically generated by rosidl,
    and these checks don't reject this value as 3.5e+100 is of float type in Python, even though it is too big for a 32-bit float.

Then, when converting this message to a C-compatible raw message before actually publishing the data, rosidl-generated conversion code casts the value to float, where it becomes inf:

// in build/proj_name/rosidl_generator_py/proj_name/msg/_type_name_s.c
ros_message->first = (float)PyFloat_AS_DOUBLE(field);

As a result, the receiving end (subscriber) receives inf.

To fix this issue, I suggest having rosidl's generator code emit boundary checks for float/double type variables, like what's done for integer types.

Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add some tests for these cases?

@squizz617
Copy link
Contributor Author

@clalancette Added tests for float/double boundaries in test/test_interfaces.py and pushed. Could you have a look?

@clalancette
Copy link
Contributor

It looks like the new tests are failing in CI, can you take a look?

@squizz617
Copy link
Contributor Author

I missed adding boundary checks for array members. Updated and passed CI tests.

@clalancette clalancette self-assigned this Apr 1, 2021
squizz617 and others added 5 commits May 19, 2021 17:02
Signed-off-by: Seulbae Kim <squizz617@gmail.com>
Signed-off-by: Seulbae Kim <squizz617@gmail.com>
Signed-off-by: Seulbae Kim <squizz617@gmail.com>
Signed-off-by: Seulbae Kim <squizz617@gmail.com>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the long delay on this. I've rebased it, and added one bugfix (to print out the bounds properly). So this is looking good to me; I'll run CI on it next.

I'm just slightly worried about this change, as it is a change in behavior. Code that used to be able to publish very large floats before will throw an exception that they never threw before. This seems OK to me, as they were publishing unexpected data, but I'd still like to get a second opinion on this before I merge it. @sloretz, what do you think?

@clalancette
Copy link
Contributor

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@oysstu
Copy link
Contributor

oysstu commented Jul 11, 2022

Please have a look at the discussion in #167. IEEE 754 mandates that a floating point number exceeding the bounds should be converted to an inf. I'm of the opinion that the behavior in python should mirror that of C/C++ if possible. At the very least I think that NaN and perhaps also Inf should pass through the bounds check without raising exceptions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants