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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list