From 1672268481829ef92f15815d4f45a3e558767a4d Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 16 Apr 2019 15:22:04 +0200 Subject: [PATCH] always append 0 byte to user/group/topic data Changes the semantics of dds_qget_{user,group,topic}data to always append a 0 byte to any non-empty value without counting it in the size. (An empty value is always represented by a null pointer and a size of 0). The advantage is that any code treating the data as the octet sequence it formally is will do exactly the same, but any code written with the knowledge that it should be a string can safely interpret it as one. Signed-off-by: Erik Boasson --- src/core/ddsc/include/dds/ddsc/dds_public_qos.h | 6 +++--- src/core/ddsc/src/dds_qos.c | 10 ++++++---- src/core/ddsi/src/q_plist.c | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/core/ddsc/include/dds/ddsc/dds_public_qos.h b/src/core/ddsc/include/dds/ddsc/dds_public_qos.h index 95fa4fe..b8fc7fa 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_public_qos.h +++ b/src/core/ddsc/include/dds/ddsc/dds_public_qos.h @@ -501,7 +501,7 @@ DDS_EXPORT void dds_qset_ignorelocal ( * @brief Get the userdata from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy - * @param[in,out] value - Pointer that will store the userdata + * @param[in,out] value - Pointer that will store the userdata. If sz = 0, then a null pointer, else it is a pointer to an allocated buffer of sz+1 bytes where the last byte is always 0 * @param[in,out] sz - Pointer that will store the size of userdata * * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object @@ -512,7 +512,7 @@ DDS_EXPORT bool dds_qget_userdata (const dds_qos_t * __restrict qos, void **valu * @brief Get the topicdata from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy - * @param[in,out] value - Pointer that will store the topicdata + * @param[in,out] value - Pointer that will store the topicdata. If sz = 0, then a null pointer, else it is a pointer to an allocated buffer of sz+1 bytes where the last byte is always 0 * @param[in,out] sz - Pointer that will store the size of topicdata * * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object @@ -523,7 +523,7 @@ DDS_EXPORT bool dds_qget_topicdata (const dds_qos_t * __restrict qos, void **val * @brief Get the groupdata from a qos structure * * @param[in] qos - Pointer to a dds_qos_t structure storing the policy - * @param[in,out] value - Pointer that will store the groupdata + * @param[in,out] value - Pointer that will store the groupdata. If sz = 0, then a null pointer, else it is a pointer to an allocated buffer of sz+1 bytes where the last byte is always 0 * @param[in,out] sz - Pointer that will store the size of groupdata * * @returns - false iff any of the arguments is invalid or the qos is not present in the qos object diff --git a/src/core/ddsc/src/dds_qos.c b/src/core/ddsc/src/dds_qos.c index 02988bf..d95add8 100644 --- a/src/core/ddsc/src/dds_qos.c +++ b/src/core/ddsc/src/dds_qos.c @@ -43,6 +43,7 @@ dds_qos_data_copy_out( void ** value, size_t * sz) { + assert (data->length < UINT32_MAX); if (sz == NULL && value != NULL) { return false; } @@ -51,9 +52,10 @@ dds_qos_data_copy_out( } if (value) { if (data->length != 0) { - assert(data->value); - *value = dds_alloc(data->length); - memcpy(*value, data->value, data->length); + assert (data->value); + *value = dds_alloc (data->length + 1); + memcpy (*value, data->value, data->length); + ((char *) (*value))[data->length] = 0; } else { *value = NULL; } @@ -66,7 +68,7 @@ validate_octetseq( const nn_octetseq_t* seq) { /* default value is NULL with length 0 */ - return (((seq->length == 0) && (seq->value == NULL)) || (seq->length > 0)); + return (((seq->length == 0) && (seq->value == NULL)) || (seq->length > 0 && seq->length < UINT32_MAX)); } bool diff --git a/src/core/ddsi/src/q_plist.c b/src/core/ddsi/src/q_plist.c index fed7f43..d44cec1 100644 --- a/src/core/ddsi/src/q_plist.c +++ b/src/core/ddsi/src/q_plist.c @@ -144,7 +144,7 @@ static int validate_octetseq (const struct dd *dd, size_t *len) if (dd->bufsz < offsetof (struct cdroctetseq, value)) return Q_ERR_INVALID; *len = dd->bswap ? bswap4u (x->len) : x->len; - if (*len > dd->bufsz - offsetof (struct cdroctetseq, value)) + if (*len > dd->bufsz - offsetof (struct cdroctetseq, value) || *len >= UINT32_MAX) return Q_ERR_INVALID; return 0; } @@ -158,7 +158,7 @@ static int alias_octetseq (nn_octetseq_t *oseq, const struct dd *dd) else { const struct cdroctetseq *x = (const struct cdroctetseq *) dd->buf; - assert(len <= UINT32_MAX); /* it really is an uint32_t on the wire */ + assert(len < UINT32_MAX); /* it really is an uint32_t on the wire */ oseq->length = (uint32_t)len; oseq->value = (len == 0) ? NULL : (unsigned char *) x->value; return 0; @@ -167,7 +167,7 @@ static int alias_octetseq (nn_octetseq_t *oseq, const struct dd *dd) static int alias_blob (nn_octetseq_t *oseq, const struct dd *dd) { - assert (dd->bufsz <= UINT32_MAX); + assert (dd->bufsz < UINT32_MAX); oseq->length = (uint32_t)dd->bufsz; oseq->value = (oseq->length == 0) ? NULL : (unsigned char *) dd->buf; return 0;