From f88ec4f337b2a755e975641697db2222ed42bca1 Mon Sep 17 00:00:00 2001 From: Simon Hancock Date: Sun, 24 Sep 2023 18:53:40 +0100 Subject: [PATCH] Mavgen C: Use strncpy instead of memcpy to pack char[n] fields Uses new macros mavlink_array_assign_[type] in place of direct calls to mav_array_memcpy. The 'char' version then uses strncpy, while others call mav_array_memcpy as before Update _mav_put_char_array function to use strncpy --- generator/C/include_v0.9/protocol.h | 34 +++++++++++++++++++++++++++-- generator/C/include_v1.0/protocol.h | 34 +++++++++++++++++++++++++++-- generator/C/include_v2.0/protocol.h | 34 +++++++++++++++++++++++++++-- generator/mavgen_c.py | 8 +++---- 4 files changed, 100 insertions(+), 10 deletions(-) diff --git a/generator/C/include_v0.9/protocol.h b/generator/C/include_v0.9/protocol.h index 26c02ef82..0abd5f0dc 100644 --- a/generator/C/include_v0.9/protocol.h +++ b/generator/C/include_v0.9/protocol.h @@ -168,13 +168,43 @@ static void mav_array_memcpy(void *dest, const void *src, size_t n) } } +/* + * Array direct assignment, for use when fields align and no byte swapping + * is required. Most are directly #defined to mav_array_memcpy, except for + * mav_array_assign_char, which uses strncpy instead. + */ +#if !MAVLINK_NEED_BYTE_SWAP && MAVLINK_ALIGNED_FIELDS +static inline void mav_array_assign_char(char *dest, const char *src, size_t n) +{ + if (src == NULL) { + memset(dest, 0, n); + } else { + /* strncpy will zero pad dest array up to n bytes */ + strncpy(dest, src, n); + } +} +#define mav_array_assign_uint8_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint8_t)) +#define mav_array_assign_int8_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int8_t)) +#define mav_array_assign_uint16_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint16_t)) +#define mav_array_assign_int16_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int16_t)) +#define mav_array_assign_uint32_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint32_t)) +#define mav_array_assign_int32_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int32_t)) +#define mav_array_assign_uint64_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint64_t)) +#define mav_array_assign_int64_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int64_t)) +#define mav_array_assign_float(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(float)) +#define mav_array_assign_double(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(double)) +#endif + /* * Place a char array into a buffer */ static inline void _mav_put_char_array(char *buf, uint8_t wire_offset, const char *b, uint8_t array_length) { - mav_array_memcpy(&buf[wire_offset], b, array_length); - + if (b == NULL) { + memset(&buf[wire_offset], 0, array_length); + } else { + strncpy(&buf[wire_offset], b, array_length); + } } /* diff --git a/generator/C/include_v1.0/protocol.h b/generator/C/include_v1.0/protocol.h index f48d947f1..25bd94af0 100644 --- a/generator/C/include_v1.0/protocol.h +++ b/generator/C/include_v1.0/protocol.h @@ -186,13 +186,43 @@ static inline void mav_array_memcpy(void *dest, const void *src, size_t n) } } +/* + * Array direct assignment, for use when fields align and no byte swapping + * is required. Most are directly #defined to mav_array_memcpy, except for + * mav_array_assign_char, which uses strncpy instead. + */ +#if !MAVLINK_NEED_BYTE_SWAP && MAVLINK_ALIGNED_FIELDS +static inline void mav_array_assign_char(char *dest, const char *src, size_t n) +{ + if (src == NULL) { + memset(dest, 0, n); + } else { + /* strncpy will zero pad dest array up to n bytes */ + strncpy(dest, src, n); + } +} +#define mav_array_assign_uint8_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint8_t)) +#define mav_array_assign_int8_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int8_t)) +#define mav_array_assign_uint16_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint16_t)) +#define mav_array_assign_int16_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int16_t)) +#define mav_array_assign_uint32_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint32_t)) +#define mav_array_assign_int32_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int32_t)) +#define mav_array_assign_uint64_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint64_t)) +#define mav_array_assign_int64_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int64_t)) +#define mav_array_assign_float(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(float)) +#define mav_array_assign_double(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(double)) +#endif + /* * Place a char array into a buffer */ static inline void _mav_put_char_array(char *buf, uint8_t wire_offset, const char *b, uint8_t array_length) { - mav_array_memcpy(&buf[wire_offset], b, array_length); - + if (b == NULL) { + memset(&buf[wire_offset], 0, array_length); + } else { + strncpy(&buf[wire_offset], b, array_length); + } } /* diff --git a/generator/C/include_v2.0/protocol.h b/generator/C/include_v2.0/protocol.h index ec593c3ac..e14b979e7 100644 --- a/generator/C/include_v2.0/protocol.h +++ b/generator/C/include_v2.0/protocol.h @@ -179,13 +179,43 @@ static inline void mav_array_memcpy(void *dest, const void *src, size_t n) } } +/* + * Array direct assignment, for use when fields align and no byte swapping + * is required. Most are directly #defined to mav_array_memcpy, except for + * mav_array_assign_char, which uses strncpy instead. + */ +#if !MAVLINK_NEED_BYTE_SWAP && MAVLINK_ALIGNED_FIELDS +static inline void mav_array_assign_char(char *dest, const char *src, size_t n) +{ + if (src == NULL) { + memset(dest, 0, n); + } else { + /* strncpy will zero pad dest array up to n bytes */ + strncpy(dest, src, n); + } +} +#define mav_array_assign_uint8_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint8_t)) +#define mav_array_assign_int8_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int8_t)) +#define mav_array_assign_uint16_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint16_t)) +#define mav_array_assign_int16_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int16_t)) +#define mav_array_assign_uint32_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint32_t)) +#define mav_array_assign_int32_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int32_t)) +#define mav_array_assign_uint64_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(uint64_t)) +#define mav_array_assign_int64_t(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(int64_t)) +#define mav_array_assign_float(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(float)) +#define mav_array_assign_double(DEST,SRC,N) mav_array_memcpy(DEST,SRC,N*sizeof(double)) +#endif + /* * Place a char array into a buffer */ static inline void _mav_put_char_array(char *buf, uint8_t wire_offset, const char *b, uint8_t array_length) { - mav_array_memcpy(&buf[wire_offset], b, array_length); - + if (b == NULL) { + memset(&buf[wire_offset], 0, array_length); + } else { + strncpy(&buf[wire_offset], b, array_length); + } } /* diff --git a/generator/mavgen_c.py b/generator/mavgen_c.py index e7f01c2e4..3e28d8fd0 100644 --- a/generator/mavgen_c.py +++ b/generator/mavgen_c.py @@ -232,7 +232,7 @@ def generate_message_h(directory, m): mavlink_${name_lower}_t packet; ${{scalar_fields: packet.${name} = ${putname}; }} -${{array_fields: mav_array_memcpy(packet.${name}, ${name}, sizeof(${type})*${array_length}); +${{array_fields: mav_array_assign_${type}(packet.${name}, ${name}, ${array_length}); }} memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, MAVLINK_MSG_ID_${name}_LEN); #endif @@ -304,7 +304,7 @@ def generate_message_h(directory, m): mavlink_${name_lower}_t packet; ${{scalar_fields: packet.${name} = ${putname}; }} -${{array_fields: mav_array_memcpy(packet.${name}, ${name}, sizeof(${type})*${array_length}); +${{array_fields: mav_array_assign_${type}(packet.${name}, ${name}, ${array_length}); }} memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, MAVLINK_MSG_ID_${name}_LEN); #endif @@ -376,7 +376,7 @@ def generate_message_h(directory, m): mavlink_${name_lower}_t packet; ${{scalar_fields: packet.${name} = ${putname}; }} -${{array_fields: mav_array_memcpy(packet.${name}, ${name}, sizeof(${type})*${array_length}); +${{array_fields: mav_array_assign_${type}(packet.${name}, ${name}, ${array_length}); }} _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_${name}, (const char *)&packet, MAVLINK_MSG_ID_${name}_MIN_LEN, MAVLINK_MSG_ID_${name}_LEN, MAVLINK_MSG_ID_${name}_CRC); #endif @@ -417,7 +417,7 @@ def generate_message_h(directory, m): mavlink_${name_lower}_t *packet = (mavlink_${name_lower}_t *)msgbuf; ${{scalar_fields: packet->${name} = ${putname}; }} -${{array_fields: mav_array_memcpy(packet->${name}, ${name}, sizeof(${type})*${array_length}); +${{array_fields: mav_array_assign_${type}(packet->${name}, ${name}, ${array_length}); }} _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_${name}, (const char *)packet, MAVLINK_MSG_ID_${name}_MIN_LEN, MAVLINK_MSG_ID_${name}_LEN, MAVLINK_MSG_ID_${name}_CRC); #endif