diff --git a/channel.c b/channel.c index 10401d595..9ff3b012e 100644 --- a/channel.c +++ b/channel.c @@ -179,20 +179,28 @@ void iio_channel_init_finalize(struct iio_channel *chn) static char *get_attr_xml(struct iio_channel_attr *attr, size_t *length) { char *str; - size_t len = strlen(attr->name) + sizeof(""); - if (attr->filename) - len += strlen(attr->filename) + sizeof("filename=\"\""); + size_t len; + len = strnlen(attr->name, MAX_ATTR_NAME); + len += sizeof("") - 1; + + if (attr->filename) { + len += strnlen(attr->filename, NAME_MAX); + len += sizeof(" filename=\"\"") - 1; + } + + *length = len; /* just the chars */ + len++; /* room for terminating NULL */ str = malloc(len); if (!str) return NULL; - *length = len - 1; /* Skip the \0 */ if (attr->filename) iio_snprintf(str, len, "", attr->name, attr->filename); else iio_snprintf(str, len, "", attr->name); + return str; } @@ -231,10 +239,13 @@ char * iio_channel_get_xml(const struct iio_channel *chn, size_t *length) size_t *attrs_len, scan_element_len = 0; unsigned int i; - len = sizeof(""); + len = sizeof("") - 1; len += strnlen(chn->id, MAX_CHN_ID); - len += chn->is_output ? sizeof("output") : sizeof("input"); - len += chn->name ? sizeof(" name= ") + strnlen(chn->name, MAX_CHN_NAME) : 0; + len += (chn->is_output ? sizeof("output") : sizeof("input")) - 1; + if (chn->name) { + len += sizeof(" name=\"\"") - 1; + len += strnlen(chn->name, MAX_CHN_NAME); + } if (chn->is_scan_element) { scan_element = get_scan_element(chn, &scan_element_len); @@ -260,6 +271,7 @@ char * iio_channel_get_xml(const struct iio_channel *chn, size_t *length) len += attrs_len[i]; } + len++; /* room for terminating NULL */ str = malloc(len); if (!str) goto err_free_attrs; @@ -307,7 +319,8 @@ char * iio_channel_get_xml(const struct iio_channel *chn, size_t *length) *length = ptr - str; - if (len < 0) { + /* NULL char should be left, and that is it */ + if (len != 1) { IIO_ERROR("Internal libIIO error: iio_channel_get_xml str length isssue\n"); free(str); return NULL; diff --git a/context.c b/context.c index aba2c9381..43373c78f 100644 --- a/context.c +++ b/context.c @@ -89,6 +89,7 @@ char * iio_context_create_xml(const struct iio_context *ctx) } } + len++; /* room for terminating NULL */ str = malloc(len); if (!str) { errno = ENOMEM; @@ -132,7 +133,7 @@ char * iio_context_create_xml(const struct iio_context *ctx) len -= sizeof("") - 1; } - if (len < 0) { + if (len != 1) { IIO_ERROR("Internal libIIO error: iio_context_create_xml str length isssue\n"); free(str); return NULL; diff --git a/device.c b/device.c index e847264a0..5ffb86ee1 100644 --- a/device.c +++ b/device.c @@ -26,9 +26,12 @@ static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type type) { - size_t len = sizeof("") + strlen(attr); + size_t len; char *str; + len = sizeof("") - 1; + len += strnlen(attr, MAX_ATTR_NAME); + switch(type){ case IIO_ATTR_TYPE_DEVICE: break; @@ -42,11 +45,12 @@ static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type t return NULL; } + *length = len; /* just the chars */ + len++; /* room for terminating NULL */ str = malloc(len); if (!str) return NULL; - *length = len - 1; /* Skip the \0 */ switch (type) { case IIO_ATTR_TYPE_DEVICE: iio_snprintf(str, len, "", attr); @@ -70,7 +74,7 @@ char * iio_device_get_xml(const struct iio_device *dev, size_t *length) size_t *attrs_len, *channels_len, *buffer_attrs_len, *debug_attrs_len; unsigned int i, j, k; - len = sizeof(" ") - 1; + len = sizeof("") - 1; len += strnlen(dev->id, MAX_DEV_ID); if (dev->name) { len += sizeof(" name=\"\"") - 1; @@ -146,6 +150,7 @@ char * iio_device_get_xml(const struct iio_device *dev, size_t *length) len += debug_attrs_len[k]; } + len++; /* room for terminating NULL */ str = malloc(len); if (!str) goto err_free_debug_attrs; @@ -222,7 +227,7 @@ char * iio_device_get_xml(const struct iio_device *dev, size_t *length) *length = ptr - str; - if (len < 0) { + if (len != 1) { IIO_ERROR("Internal libIIO error: iio_device_get_xml str length isssue\n"); free(str); return NULL; diff --git a/iio-private.h b/iio-private.h index dafcfd841..4e82b3d22 100644 --- a/iio-private.h +++ b/iio-private.h @@ -60,15 +60,30 @@ #define CLEAR_BIT(addr, bit) \ *(((uint32_t *) addr) + BIT_WORD(bit)) &= ~BIT_MASK(bit) -/* 256 is the MAX_NAME (file name) on Linux, 4096 is PAGESIZE */ -#define MAX_CHN_ID 256 /* encoded in the sysfs filename */ -#define MAX_CHN_NAME 256 /* encoded in the sysfs filename */ -#define MAX_DEV_ID 256 /* encoded in the sysfs filename */ -#define MAX_DEV_NAME 256 /* encoded in the sysfs filename */ -#define MAX_CTX_NAME 256 /* nominally "xml" */ -#define MAX_CTX_DESC 256 /* nominally "linux ..." */ -#define MAX_ATTR_NAME 256 /* encoded in the sysfs filename */ -#define MAX_ATTR_VALUE 4096 /* Linux page size, could be anything */ +/* https://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html + * {NAME_MAX} : Maximum number of bytes in a filename + * {PATH_MAX} : Maximum number of bytes in a pathname + * {PAGESIZE} : Size in bytes of a page + * Too bad we work on non-POSIX systems + */ +#ifndef NAME_MAX +#define NAME_MAX 256 +#endif +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif +#ifndef PAGESIZE +#define PAGESIZE 4096 +#endif + +#define MAX_CHN_ID NAME_MAX /* encoded in the sysfs filename */ +#define MAX_CHN_NAME NAME_MAX /* encoded in the sysfs filename */ +#define MAX_DEV_ID NAME_MAX /* encoded in the sysfs filename */ +#define MAX_DEV_NAME NAME_MAX /* encoded in the sysfs filename */ +#define MAX_CTX_NAME NAME_MAX /* nominally "xml" */ +#define MAX_CTX_DESC NAME_MAX /* nominally "linux ..." */ +#define MAX_ATTR_NAME NAME_MAX /* encoded in the sysfs filename */ +#define MAX_ATTR_VALUE PAGESIZE /* Linux page size, could be anything */ /* ntohl/htonl are a nightmare to use in cross-platform applications, * since they are defined in different headers on different platforms.