Skip to content

Commit a0343f3

Browse files
committed
xml buildups: fix bug introduced by recent changes
be more pedanic about the differences between strlen (doesn't include null char) and sizeof (which does include null char). Now, we calculate the exact length the the string (number of char) add one for malloc, fill everything out, and then check it make sure the length is one (the null char) left. tested on host and local (Zedboard + FMCOMMS2) Signed-off-by: Robin Getz <[email protected]>
1 parent 168d165 commit a0343f3

File tree

4 files changed

+56
-22
lines changed

4 files changed

+56
-22
lines changed

channel.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,20 +179,28 @@ void iio_channel_init_finalize(struct iio_channel *chn)
179179
static char *get_attr_xml(struct iio_channel_attr *attr, size_t *length)
180180
{
181181
char *str;
182-
size_t len = strlen(attr->name) + sizeof("<attribute name=\"\" />");
183-
if (attr->filename)
184-
len += strlen(attr->filename) + sizeof("filename=\"\"");
182+
size_t len;
185183

184+
len = strnlen(attr->name, MAX_ATTR_NAME);
185+
len += sizeof("<attribute name=\"\" />") - 1;
186+
187+
if (attr->filename) {
188+
len += strnlen(attr->filename, NAME_MAX);
189+
len += sizeof(" filename=\"\"") - 1;
190+
}
191+
192+
*length = len; /* just the chars */
193+
len++; /* room for terminating NULL */
186194
str = malloc(len);
187195
if (!str)
188196
return NULL;
189197

190-
*length = len - 1; /* Skip the \0 */
191198
if (attr->filename)
192199
iio_snprintf(str, len, "<attribute name=\"%s\" filename=\"%s\" />",
193200
attr->name, attr->filename);
194201
else
195202
iio_snprintf(str, len, "<attribute name=\"%s\" />", attr->name);
203+
196204
return str;
197205
}
198206

@@ -231,10 +239,13 @@ char * iio_channel_get_xml(const struct iio_channel *chn, size_t *length)
231239
size_t *attrs_len, scan_element_len = 0;
232240
unsigned int i;
233241

234-
len = sizeof("<channel id=\"\" type=\"\" ></channel>");
242+
len = sizeof("<channel id=\"\" type=\"\" ></channel>") - 1;
235243
len += strnlen(chn->id, MAX_CHN_ID);
236-
len += chn->is_output ? sizeof("output") : sizeof("input");
237-
len += chn->name ? sizeof(" name= ") + strnlen(chn->name, MAX_CHN_NAME) : 0;
244+
len += (chn->is_output ? sizeof("output") : sizeof("input")) - 1;
245+
if (chn->name) {
246+
len += sizeof(" name=\"\"") - 1;
247+
len += strnlen(chn->name, MAX_CHN_NAME);
248+
}
238249

239250
if (chn->is_scan_element) {
240251
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)
260271
len += attrs_len[i];
261272
}
262273

274+
len++; /* room for terminating NULL */
263275
str = malloc(len);
264276
if (!str)
265277
goto err_free_attrs;
@@ -307,7 +319,8 @@ char * iio_channel_get_xml(const struct iio_channel *chn, size_t *length)
307319

308320
*length = ptr - str;
309321

310-
if (len < 0) {
322+
/* NULL char should be left, and that is it */
323+
if (len != 1) {
311324
IIO_ERROR("Internal libIIO error: iio_channel_get_xml str length isssue\n");
312325
free(str);
313326
return NULL;

context.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ char * iio_context_create_xml(const struct iio_context *ctx)
8989
}
9090
}
9191

92+
len++; /* room for terminating NULL */
9293
str = malloc(len);
9394
if (!str) {
9495
errno = ENOMEM;
@@ -132,7 +133,7 @@ char * iio_context_create_xml(const struct iio_context *ctx)
132133
len -= sizeof("</context>") - 1;
133134
}
134135

135-
if (len < 0) {
136+
if (len != 1) {
136137
IIO_ERROR("Internal libIIO error: iio_context_create_xml str length isssue\n");
137138
free(str);
138139
return NULL;

device.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@
2626

2727
static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type type)
2828
{
29-
size_t len = sizeof("<attribute name=\"\" />") + strlen(attr);
29+
size_t len;
3030
char *str;
3131

32+
len = sizeof("<attribute name=\"\" />") - 1;
33+
len += strnlen(attr, MAX_ATTR_NAME);
34+
3235
switch(type){
3336
case IIO_ATTR_TYPE_DEVICE:
3437
break;
@@ -42,11 +45,12 @@ static char *get_attr_xml(const char *attr, size_t *length, enum iio_attr_type t
4245
return NULL;
4346
}
4447

48+
*length = len; /* just the chars */
49+
len++; /* room for terminating NULL */
4550
str = malloc(len);
4651
if (!str)
4752
return NULL;
4853

49-
*length = len - 1; /* Skip the \0 */
5054
switch (type) {
5155
case IIO_ATTR_TYPE_DEVICE:
5256
iio_snprintf(str, len, "<attribute name=\"%s\" />", attr);
@@ -70,7 +74,7 @@ char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
7074
size_t *attrs_len, *channels_len, *buffer_attrs_len, *debug_attrs_len;
7175
unsigned int i, j, k;
7276

73-
len = sizeof("<device id=\"\" ></device> ") - 1;
77+
len = sizeof("<device id=\"\" ></device>") - 1;
7478
len += strnlen(dev->id, MAX_DEV_ID);
7579
if (dev->name) {
7680
len += sizeof(" name=\"\"") - 1;
@@ -146,6 +150,7 @@ char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
146150
len += debug_attrs_len[k];
147151
}
148152

153+
len++; /* room for terminating NULL */
149154
str = malloc(len);
150155
if (!str)
151156
goto err_free_debug_attrs;
@@ -222,7 +227,7 @@ char * iio_device_get_xml(const struct iio_device *dev, size_t *length)
222227

223228
*length = ptr - str;
224229

225-
if (len < 0) {
230+
if (len != 1) {
226231
IIO_ERROR("Internal libIIO error: iio_device_get_xml str length isssue\n");
227232
free(str);
228233
return NULL;

iio-private.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,30 @@
6060
#define CLEAR_BIT(addr, bit) \
6161
*(((uint32_t *) addr) + BIT_WORD(bit)) &= ~BIT_MASK(bit)
6262

63-
/* 256 is the MAX_NAME (file name) on Linux, 4096 is PAGESIZE */
64-
#define MAX_CHN_ID 256 /* encoded in the sysfs filename */
65-
#define MAX_CHN_NAME 256 /* encoded in the sysfs filename */
66-
#define MAX_DEV_ID 256 /* encoded in the sysfs filename */
67-
#define MAX_DEV_NAME 256 /* encoded in the sysfs filename */
68-
#define MAX_CTX_NAME 256 /* nominally "xml" */
69-
#define MAX_CTX_DESC 256 /* nominally "linux ..." */
70-
#define MAX_ATTR_NAME 256 /* encoded in the sysfs filename */
71-
#define MAX_ATTR_VALUE 4096 /* Linux page size, could be anything */
63+
/* https://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
64+
* {NAME_MAX} : Maximum number of bytes in a filename
65+
* {PATH_MAX} : Maximum number of bytes in a pathname
66+
* {PAGESIZE} : Size in bytes of a page
67+
* Too bad we work on non-POSIX systems
68+
*/
69+
#ifndef NAME_MAX
70+
#define NAME_MAX 256
71+
#endif
72+
#ifndef PATH_MAX
73+
#define PATH_MAX 4096
74+
#endif
75+
#ifndef PAGESIZE
76+
#define PAGESIZE 4096
77+
#endif
78+
79+
#define MAX_CHN_ID NAME_MAX /* encoded in the sysfs filename */
80+
#define MAX_CHN_NAME NAME_MAX /* encoded in the sysfs filename */
81+
#define MAX_DEV_ID NAME_MAX /* encoded in the sysfs filename */
82+
#define MAX_DEV_NAME NAME_MAX /* encoded in the sysfs filename */
83+
#define MAX_CTX_NAME NAME_MAX /* nominally "xml" */
84+
#define MAX_CTX_DESC NAME_MAX /* nominally "linux ..." */
85+
#define MAX_ATTR_NAME NAME_MAX /* encoded in the sysfs filename */
86+
#define MAX_ATTR_VALUE PAGESIZE /* Linux page size, could be anything */
7287

7388
/* ntohl/htonl are a nightmare to use in cross-platform applications,
7489
* since they are defined in different headers on different platforms.

0 commit comments

Comments
 (0)