[libvirt] [PATCH 2/3] Add virBufferEscapeShell

Guido Günther agx at sigxcpu.org
Wed Oct 12 22:39:49 UTC 2011


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




More information about the libvir-list mailing list