Index: src/buf.c
===================================================================
RCS file: /data/cvs/libxen/src/buf.c,v
retrieving revision 1.2
diff -u -p -r1.2 buf.c
--- src/buf.c 29 Jun 2007 13:23:13 -0000 1.2
+++ src/buf.c 6 Jul 2007 13:31:34 -0000
@@ -185,6 +185,82 @@ virBufferVSprintf(virBufferPtr buf, cons
}
/**
+ * virBufferEscapeString:
+ * @buf: the buffer to dump
+ * @format: a printf like format string but with only one %s parameter
+ * @str: the string argument which need to be escaped
+ *
+ * Do a formatted print with a single string to an XML buffer. The string
+ * is escaped to avoid generating a not well-formed XML instance.
+ *
+ * Returns 0 successful, -1 in case of internal or API error.
+ */
+int
+virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
+{
+ int size, count, len;
+ char *escaped, *out;
+ const char *cur;
+
+ if ((format == NULL) || (buf == NULL) || (str == NULL)) {
+ return (-1);
+ }
+
+ len = strlen(str);
+ escaped = malloc(5 * len + 1);
+ if (escaped == NULL) {
+ return (-1);
+ }
+ cur = str;
+ out = escaped;
+ while (*cur != 0) {
+ if (*cur == '<') {
+ *out++ = '&';
+ *out++ = 'l';
+ *out++ = 'l';
+ *out++ = ';';
+ } else if (*cur == '>') {
+ *out++ = '&';
+ *out++ = 'g';
+ *out++ = 't';
+ *out++ = ';';
+ } else if (*cur == '&') {
+ *out++ = '&';
+ *out++ = 'a';
+ *out++ = 'm';
+ *out++ = 'p';
+ *out++ = ';';
+ } else if ((*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
+ (*cur == '\r')) {
+ /*
+ * default case, just copy !
+ * Note that character over 0x80 are likely to give problem
+ * with UTF-8 XML, but since our string don't have an encoding
+ * it's hard to handle properly we have to assume it's UTF-8 too
+ */
+ *out++ = *cur;
+ }
+ cur++;
+ }
+ *out = 0;
+
+ size = buf->size - buf->use - 1;
+ while (((count = snprintf(&buf->content[buf->use], size, format,
+ (char *)escaped)) < 0) || (count >= size - 1)) {
+ buf->content[buf->use] = 0;
+ if (virBufferGrow(buf, 1000) < 0) {
+ free(escaped);
+ return (-1);
+ }
+ size = buf->size - buf->use - 1;
+ }
+ buf->use += count;
+ buf->content[buf->use] = 0;
+ free(escaped);
+ return (0);
+}
+
+/**
* virBufferStrcat:
* @buf: the buffer to dump
* @...: the variable list of strings, the last argument must be NULL
Index: src/buf.h
===================================================================
RCS file: /data/cvs/libxen/src/buf.h,v
retrieving revision 1.1
diff -u -p -r1.1 buf.h
--- src/buf.h 26 Jun 2007 22:33:22 -0000 1.1
+++ src/buf.h 6 Jul 2007 13:31:34 -0000
@@ -33,5 +33,6 @@ int virBufferAdd(virBufferPtr buf, const
int virBufferVSprintf(virBufferPtr buf, const char *format, ...)
ATTRIBUTE_FORMAT(printf, 2, 3);
int virBufferStrcat(virBufferPtr buf, ...);
+int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str);
#endif /* __VIR_BUFFER_H__ */
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libxen/src/xend_internal.c,v
retrieving revision 1.126
diff -u -p -r1.126 xend_internal.c
--- src/xend_internal.c 5 Jul 2007 16:04:12 -0000 1.126
+++ src/xend_internal.c 6 Jul 2007 13:31:34 -0000
@@ -1337,7 +1337,7 @@ xend_parse_sexp_desc_os(virConnectPtr xe
virBufferVSprintf(buf, " %s\n", tmp);
tmp = sexpr_node(node, "domain/image/linux/args");
if ((tmp != NULL) && (tmp[0] != 0))
- virBufferVSprintf(buf, " %s\n", tmp);
+ virBufferEscapeString(buf, " %s\n", tmp);
}
virBufferAdd(buf, " \n", 8);
@@ -1423,7 +1423,7 @@ xend_parse_sexp_desc(virConnectPtr conn,
/*
* Only insert bootloader_args if there is also a bootloader param
*/
- virBufferVSprintf(&buf, " %s\n", tmp);
+ virBufferEscapeString(&buf, " %s\n", tmp);
}
if (domid != 0) {
Index: src/xm_internal.c
===================================================================
RCS file: /data/cvs/libxen/src/xm_internal.c,v
retrieving revision 1.34
diff -u -p -r1.34 xm_internal.c
--- src/xm_internal.c 4 Jul 2007 13:16:57 -0000 1.34
+++ src/xm_internal.c 6 Jul 2007 13:31:34 -0000
@@ -663,7 +663,7 @@ char *xenXMDomainFormatXML(virConnectPtr
if (xenXMConfigGetString(conf, "bootloader", &str) == 0)
virBufferVSprintf(buf, " %s\n", str);
if (xenXMConfigGetString(conf, "bootargs", &str) == 0)
- virBufferVSprintf(buf, " %s\n", str);
+ virBufferEscapeString(buf, " %s\n", str);
if (xenXMConfigGetString(conf, "kernel", &str) == 0) {
virBufferAdd(buf, " \n", -1);
virBufferAdd(buf, " linux\n", -1);
@@ -671,7 +671,7 @@ char *xenXMDomainFormatXML(virConnectPtr
if (xenXMConfigGetString(conf, "ramdisk", &str) == 0)
virBufferVSprintf(buf, " %s\n", str);
if (xenXMConfigGetString(conf, "extra", &str) == 0)
- virBufferVSprintf(buf, " %s\n", str);
+ virBufferEscapeString(buf, " %s\n", str);
virBufferAdd(buf, " \n", -1);
}
}