Skip to content

Commit

Permalink
xml: Add capability to properly encode xml entities in context attrib…
Browse files Browse the repository at this point in the history
…utes

Per #519, xml entities (<, >, ", ', and &) were not encoded properly, and if
used in the libiio.ini file (which was added in 77568c7 )
cause the libiio library to fail.

This fixed that by adding a generic way to encode things in xml.c and uses them in context.c

Right now, we only encode context attributes. In theory this could also effect:
 - attribute name
 - buffer-attribute name
 - channel id
 - context name
 - debug-attribute name
 - device id
 - scan-element index
Since most of those are encoded in file names, we shouldn't have those chars
anyway. Now that we know the issue, and understand the fix, if anyone sees
any issues, please feel free to report.

Tested on Zed + FMCOMMS3, with both 0.19 (with fix) and old libraries without fix.
As long as the the version which is reading the file has the fix - it works with
older libraries (is backwards compatible).

Signed-off-by: Robin Getz <[email protected]>
  • Loading branch information
rgetz committed Jun 2, 2020
1 parent baacae9 commit 71bdda5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
41 changes: 37 additions & 4 deletions context.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ char * iio_context_create_xml(const struct iio_context *ctx)
ssize_t len;
size_t *devices_len = NULL;
char *str, *ptr, *eptr, **devices = NULL;
char ** ctx_attrs, **ctx_values;
unsigned int i;

len = sizeof(xml_header) - 1;
Expand All @@ -61,17 +62,33 @@ char * iio_context_create_xml(const struct iio_context *ctx)
len += sizeof(" description=\"\"") - 1;
}

ctx_attrs = calloc(ctx->nb_attrs, sizeof(ctx->attrs));
if (!ctx_attrs) {
errno = ENOMEM;
return NULL;
}
ctx_values = calloc(ctx->nb_attrs, sizeof(ctx->values));
if (!ctx_values) {
errno = ENOMEM;
goto err_free_ctx_attrs;
}

for (i = 0; i < ctx->nb_attrs; i++) {
len += strnlen(ctx->attrs[i], MAX_ATTR_NAME);
len += strnlen(ctx->values[i], MAX_ATTR_VALUE);
ctx_attrs[i] = encode_xml_ndup(ctx->attrs[i]);
ctx_values[i] = encode_xml_ndup(ctx->values[i]);
if (!ctx_attrs[i] || !ctx_values[i])
goto err_free_ctx_attrs_values;

len += strnlen(ctx_attrs[i], MAX_ATTR_NAME);
len += strnlen(ctx_values[i], MAX_ATTR_VALUE);
len += sizeof("<context-attribute name=\"\" value=\"\" />") - 1;
}

if (ctx->nb_devices) {
devices_len = malloc(ctx->nb_devices * sizeof(*devices_len));
if (!devices_len) {
errno = ENOMEM;
return NULL;
goto err_free_ctx_attrs_values;
}

devices = calloc(ctx->nb_devices, sizeof(*devices));
Expand Down Expand Up @@ -111,10 +128,15 @@ char * iio_context_create_xml(const struct iio_context *ctx)

for (i = 0; i < ctx->nb_attrs && len > 0; i++) {
ptr += iio_snprintf(ptr, len, "<context-attribute name=\"%s\" value=\"%s\" />",
ctx->attrs[i], ctx->values[i]);
ctx_attrs[i], ctx_values[i]);
free(ctx_attrs[i]);
free(ctx_values[i]);
len = eptr - ptr;
}

free(ctx_attrs);
free(ctx_values);

for (i = 0; i < ctx->nb_devices; i++) {
if (len > (ssize_t) devices_len[i]) {
memcpy(ptr, devices[i], devices_len[i]); /* Flawfinder: ignore */
Expand Down Expand Up @@ -146,6 +168,17 @@ char * iio_context_create_xml(const struct iio_context *ctx)
free(devices);
err_free_devices_len:
free(devices_len);
err_free_ctx_attrs_values:
for (i = 0; i < ctx->nb_attrs; i++) {
if (ctx_attrs[i])
free(ctx_attrs[i]);
if (ctx_values[i])
free(ctx_values[i]);
}

free(ctx_values);
err_free_ctx_attrs:
free(ctx_attrs);
return NULL;
}

Expand Down
1 change: 1 addition & 0 deletions iio-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ void free_device(struct iio_device *dev);
char *iio_channel_get_xml(const struct iio_channel *chn, size_t *len);
char *iio_device_get_xml(const struct iio_device *dev, size_t *len);

char *encode_xml_ndup(const char * input);
char *iio_context_create_xml(const struct iio_context *ctx);
int iio_context_init(struct iio_context *ctx);

Expand Down
10 changes: 10 additions & 0 deletions xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
#include <libxml/tree.h>
#include <string.h>

/* 'input' must be in UTF-8 encoded, null terminated */
char * encode_xml_ndup(const char * input)
{
char * out;

out = (char *)xmlEncodeEntitiesReentrant(NULL, (const xmlChar *)input);

return out;
}

static int add_attr_to_channel(struct iio_channel *chn, xmlNode *n)
{
xmlAttr *attr;
Expand Down

0 comments on commit 71bdda5

Please sign in to comment.