Add virBufferEscapeShellXMLComment function that both quotes a string so
shell deosn't interpert any special characters in it and makes sure that
there's no "--" in it, to avoid clashes with XML comments.
virXMLEmitWarning is changed to use virBuffer and use the above function
on the domain name.
---
src/libvirt_private.syms | 1 +
src/util/buf.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/buf.h | 1 +
src/util/xml.c | 52 +++++++++++++++---------------------
4 files changed, 90 insertions(+), 30 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 699c9a3..a49d5dc 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -37,6 +37,7 @@ virBufferError;
virBufferEscape;
virBufferEscapeSexpr;
virBufferEscapeShell;
+virBufferEscapeShellXML;
virBufferEscapeString;
virBufferFreeAndReset;
virBufferGetIndent;
diff --git a/src/util/buf.c b/src/util/buf.c
index 030dc97..839b663 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -623,6 +623,72 @@ virBufferEscapeShell(virBufferPtr buf, const char *str)
}
/**
+ * virBufferEscapeShellXMLComment:
+ * @buf: the buffer to append to
+ * @str: an unquoted string
+ *
+ * Quotes a string so that the shell (/bin/sh) will interpret the
+ * quoted string to mean str. Auto indentation may be applied.
+ * It also escapes any "--" so that the string can be used in XML comments.
+ */
+void virBufferEscapeShellXMLComment(virBufferPtr buf, const char *str)
+{
+ int len;
+ char *escaped, *out;
+ const char *cur;
+ char prev = '\0';
+
+ if ((buf == NULL) || (str == NULL))
+ return;
+
+ if (buf->error)
+ return;
+
+ /* Only quote if str includes shell metacharacters. */
+ if (*str && !strpbrk(str, "\r\t\n
!\"#$&'()*;<>?[\\]^`{|}~") &&
+ !strstr(str,"--")) {
+ virBufferAdd(buf, str, -1);
+ return;
+ }
+
+ if (*str) {
+ len = strlen(str);
+ if (xalloc_oversized(4, len) ||
+ VIR_ALLOC_N(escaped, 4 * len + 3) < 0) {
+ virBufferSetError(buf, errno);
+ return;
+ }
+ } else {
+ virBufferAddLit(buf, "''");
+ return;
+ }
+
+ cur = str;
+ out = escaped;
+
+ *out++ = '\'';
+ while (*cur != 0) {
+ if (*cur == '\'') {
+ *out++ = '\'';
+ /* Replace literal ' with a close ', a \', and a open ' */
+ *out++ = '\\';
+ *out++ = '\'';
+ } else if (*cur == '-' && prev == '-') {
+ /* Replace -- with -''- */
+ *out++ = '\'';
+ *out++ = '\'';
+ }
+ prev = *cur;
+ *out++ = *cur++;
+ }
+ *out++ = '\'';
+ *out = 0;
+
+ virBufferAdd(buf, escaped, -1);
+ VIR_FREE(escaped);
+}
+
+/**
* virBufferStrcat:
* @buf: the buffer to append to
* @...: the variable list of strings, the last argument must be NULL
diff --git a/src/util/buf.h b/src/util/buf.h
index c3a498d..25e31fd 100644
--- a/src/util/buf.h
+++ b/src/util/buf.h
@@ -69,6 +69,7 @@ void virBufferEscapeString(virBufferPtr buf, const char *format,
void virBufferEscapeSexpr(virBufferPtr buf, const char *format,
const char *str);
void virBufferEscapeShell(virBufferPtr buf, const char *str);
+void virBufferEscapeShellXMLComment(virBufferPtr buf, const char *str);
void virBufferURIEncodeString(virBufferPtr buf, const char *str);
# define virBufferAddLit(buf_, literal_string_) \
diff --git a/src/util/xml.c b/src/util/xml.c
index f3dc256..685f903 100644
--- a/src/util/xml.c
+++ b/src/util/xml.c
@@ -780,49 +780,41 @@ error:
goto cleanup;
}
-
static int virXMLEmitWarning(int fd,
const char *name,
const char *cmd)
{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *str = NULL;
size_t len;
- const char *prologue = "<!--\n\
-WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE \n\
-OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n\
- virsh ";
- const char *epilogue = "\n\
-or other application using the libvirt API.\n\
--->\n\n";
if (fd < 0 || !name || !cmd) {
errno = EINVAL;
return -1;
}
- len = strlen(prologue);
- if (safewrite(fd, prologue, len) != len)
- return -1;
-
- len = strlen(cmd);
- if (safewrite(fd, cmd, len) != len)
- return -1;
-
- /* Omit the domain name if it contains a double hyphen
- * because they aren't allowed in XML comments */
- if (!strstr(name, "--")) {
- if (safewrite(fd, " ", 1) != 1)
- return -1;
-
- len = strlen(name);
- if (safewrite(fd, name, len) != len)
- return -1;
+ virBufferAddLit(&buf, "<!--\n"
+"WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\n"
+"OVERWRITTEN AND LOST. Changes to this xml configuration should be made
using:\n"
+" virsh ");
+ virBufferAdd(&buf, cmd, -1);
+ virBufferAddLit(&buf," ");
+ virBufferEscapeShellXMLComment(&buf, name);
+ virBufferAddLit(&buf, "\n"
+"or other application using the libvirt API.\n"
+"-->\n\n");
+
+ str = virBufferContentAndReset(&buf);
+ if (str) {
+ len = strlen(str);
+ if (safewrite(fd, str, len) == len) {
+ VIR_FREE(str);
+ return 0;
+ }
}
- len = strlen(epilogue);
- if (safewrite(fd, epilogue, len) != len)
- return -1;
-
- return 0;
+ VIR_FREE(str);
+ return -1;
}
--
1.7.8.6