ros2 / ros2/rosidl_python

Multiple issues in array data setter

Open
#153 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

help wanted
Dominant language
EmberScript
Stars
26
Forks
68
Avg merge
2d 13h
Merged PRs (30d)
1

Description

Bug report

Required Info:

  • Operating System:
    • Ubuntu 20.04
  • Installation type:
    • Binary installation via apt
  • Version or commit hash:
    • foxy
  • DDS implementation:
    • Fast-RTPS
  • Client library (if applicable):
    • N/A
Steps to reproduce issue
  1. Clone and build messages
$ mkdir -p ~/idltest_ws/src
$ cd ~/idltest_ws/src
$ git clone git@github.com:squizz617/idltest_msgs.git
$ cd ~/idltest_ws
$ colcon build --symlink-install
  1. Source workspaces (replace zsh with bash if using Bash)
$ source /opt/ros/foxy/setup.zsh
$ source ~/idltest_ws/install/setup.zsh
  1. Download and run PoC
$ wget https://gist.githubusercontent.com/squizz617/13631a18d25a1b7836414cce0c579227/raw/3e5113c78f2b1b7fe3296a2b29298afad6d8349e/poc_idl_array.py
$ chmod a+x poc_idl_array.py
$ ./poc_idl_array.py
Expected behavior

The PoC is self-explanatory. On the fixed arrays of built-in types, it tests the following three properties: (1) setting legitimate values should succeed, (2) setting out-of-valid-range values should fail, and (3) setting values of mismatching types should fail.

Actual behavior

The issues can be broadly categorized into three types.

  1. Missing range checks for numeric type (integer and float) arrays

uint8 array allows out of range integers to be assigned:

from idltest_msgs.msg import UInt8FixedArray
ui8fa = UInt8FixedArray()
ui8fa.data[0] = -1 # should fail but doesn't
print(ui8fa.data[0]) # value becomes 255
ui8fa.data[1] = 256 # should fail but doesn't
print(ui8fa.data[1]) # value becomes 0

int8 array also allows out of range integers to be assigned:

from idltest_msgs.msg import Int8FixedArray
i8fa = Int8FixedArray()
ui8fa.data[0] = -129 # should fail but doesn't
print(ui8fa.data[0]) # value becomes 127
ui8fa.data[1] = 128 # should fail but doesn't
print(ui8fa.data[1]) # value becomes -128

float32 array allows double to be assigned:

from idltest_msgs.msg import Float32FixedArray
f32fa = Float32FixedArray()
f32fa.data[0] = 1.0e+365 # should fail but doesn't
print(f32fa.data[0]) # value becomes inf
  1. Auto casting of data of wrong types

Integer arrays accept floats and casts them to int, dropping precision:

i8fa = Int8FixedArray()
i8fa.data[2] = 3.141592 # should fail but doesn't
print(i8fa.data[2]) # value becomes 3
i8fa.data[3] = 314.1592 # should fail but doesn't
print(i8fa.data[3]) # value becomes 58

For the types that cannot be casted to int, the assignment fails but the exception is raised not by the IDL:

i8fa.data[4] = "string" # fails (int() casting failure, not idl type check failure)
i8fa.data[5] = \x00 # fails (int() casting failure, not idl type check failure)
  1. Missing type checks for bool, byte, and string arrays

Any data of any type can be assigned to bool, byte or string arrays:

boolfa = BoolFixedArray()
bytefa = ByteFixedArray()
sfa = StringFixedArray()

# nothing fails
boolfa.data[0] = 32
boolfa.data[1] = 3.141592
boolfa.data[2] = 1.0e+365
boolfa.data[3] = 3.141592
boolfa.data[4] = "string"
boolfa.data[5] = [1, 2, 3]
boolfa.data[6] = {1: 2}
print(boolfa) # the illegitimate values are assigned as is

bytefa.data[0] = 32
bytefa.data[1] = 3.141592
bytefa.data[2] = 1.0e+365
bytefa.data[3] = 3.141592
bytefa.data[4] = "string"
bytefa.data[5] = [1, 2, 3]
bytefa.data[6] = {1: 2}
print(bytefa) # the illegitimate values are assigned as is

sfa.data[0] = 32
sfa.data[1] = 3.141592
sfa.data[2] = 1.0e+365
sfa.data[3] = 3.141592
sfa.data[4] = [1, 2, 3]
sfa.data[5] = {1: 2}
print(sfa) # the illegitimate values are assigned as is

In a nutshell, array elements are not properly checked at the time of assignment, unlike what's done for the built-in types (e.g., we cannot assign 256 or 3.14 to a uint8 variable, we cannot assign 3.14 to a string variable, ...).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked poc_idl_array.py reproduction and compare array-element assignment with the built-in type behavior described in the issue. Trace the generated Python message classes for fixed arrays, then add coverage for range and type rejection across numeric, bool, byte, and string arrays; done means the invalid assignments fail consistently while legitimate values still succeed.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.