Escape strings so they're safe to pass to the shell. Based on glib's
g_quote_string.
---
src/libvirt_private.syms | 1 +
src/util/buf.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/buf.h | 1 +
3 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4f96518..862f3ac 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -29,6 +29,7 @@ virBufferEscape;
virBufferEscapeSexpr;
virBufferEscapeString;
virBufferFreeAndReset;
+virBufferEscapeShell;
virBufferStrcat;
virBufferURIEncodeString;
virBufferUse;
diff --git a/src/util/buf.c b/src/util/buf.c
index fa12855..f9d7cd7 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -486,6 +486,60 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
}
/**
+ * virBufferEscapeShell:
+ * @buf: the buffer to append to
+ * @str: an unquoted string
+ *
+ * Quotes a string so that the shell (/bin/sh) will interpret the
+ * quoted string as unquoted_string.
+ */
+void
+virBufferEscapeShell(const virBufferPtr buf, const char *str)
+{
+ int len;
+ bool close_quote = false;
+ char *escaped, *out;
+ const char *cur;
+
+ if ((buf == NULL) || (str == NULL))
+ return;
+
+ if (buf->error)
+ return;
+
+ len = strlen(str);
+ if (xalloc_oversized(4, len) ||
+ VIR_ALLOC_N(escaped, 4 * len + 3) < 0) {
+ virBufferSetError(buf);
+ return;
+ }
+
+ cur = str;
+ out = escaped;
+
+ /* Add outer '...' only if arg included shell metacharacters. */
+ if (strpbrk(str, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~")) {
+ *out++ = '\'';
+ close_quote = true;
+ }
+ while (*cur != 0) {
+ if (*cur == '\'') {
+ /* Replace literal ' with a close ', a \', and a open ' */
+ *out++ = '\'';
+ *out++ = '\\';
+ *out++ = *cur++;
+ *out++ = '\'';
+ } else
+ *out++ = *cur++;
+ }
+ if (close_quote)
+ *out++ = '\'';
+ *out = 0;
+ virBufferAdd(buf, escaped, -1);
+ VIR_FREE(escaped);
+}
+
+/**
* virBufferStrcat:
* @buf: the buffer to dump
* @...: the variable list of strings, the last argument must be NULL
diff --git a/src/util/buf.h b/src/util/buf.h
index e545ed9..ad8ef86 100644
--- a/src/util/buf.h
+++ b/src/util/buf.h
@@ -52,6 +52,7 @@ void virBufferEscapeString(const virBufferPtr buf, const char *format,
const cha
void virBufferEscapeSexpr(const virBufferPtr buf, const char *format, const char *str);
void virBufferEscape(const virBufferPtr buf, const char *toescape, const char *format,
const char *str);
void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
+void virBufferEscapeShell(const virBufferPtr buf, const char *str);
# define virBufferAddLit(buf_, literal_string_) \
virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ -
1)
--
1.7.6.3