Add virStringHasControlChars that checks if the string has
any control characters other than \t\r\n,
and virStringStripControlChars that removes them in-place.
---
src/libvirt_private.syms | 2 ++
src/util/virstring.c | 39 +++++++++++++++++++++++++++++++++++++++
src/util/virstring.h | 2 ++
tests/virstringtest.c | 39 +++++++++++++++++++++++++++++++++++++++
4 files changed, 82 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7166283..d37a6b5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2134,6 +2134,7 @@ virStrdup;
virStringArrayHasString;
virStringFreeList;
virStringFreeListCount;
+virStringHasControlChars;
virStringIsEmpty;
virStringJoin;
virStringListLength;
@@ -2143,6 +2144,7 @@ virStringSortCompare;
virStringSortRevCompare;
virStringSplit;
virStringSplitCount;
+virStringStripControlChars;
virStringStripIPv6Brackets;
virStrncpy;
virStrndup;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 3dad9dd..9eb48b5 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -968,3 +968,42 @@ virStringStripIPv6Brackets(char *str)
str[len - 2] = '\0';
}
}
+
+static const char control_chars[] =
+ "\x01\x02\x03\x04\x05\x06\x07"
+ "\x08" /* \t \n */ "\x0B\x0C" /* \r */ "\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+
+bool
+virStringHasControlChars(const char *str)
+{
+ if (!str)
+ return false;
+
+ return strcspn(str, control_chars) != strlen(str);
+}
+/**
+ * virStringStripControlChars:
+ * @str: the string to strip
+ *
+ * Modify the string in-place to remove the control characters
+ * in the interval: (0x01, 0x20)
+ */
+void
+virStringStripControlChars(char *str)
+{
+ size_t len, i, j;
+
+ if (!virStringHasControlChars(str))
+ return;
+
+ len = strlen(str);
+ for (i = 0, j = 0; i < len; i++) {
+ if (index(control_chars, str[i]))
+ continue;
+
+ str[j++] = str[i];
+ }
+ str[j] = '\0';
+}
diff --git a/src/util/virstring.h b/src/util/virstring.h
index 2ec60fa..e6dcb32 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -271,5 +271,7 @@ char *virStringReplace(const char *haystack,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
void virStringStripIPv6Brackets(char *str);
+bool virStringHasControlChars(const char *str);
+void virStringStripControlChars(char *str);
#endif /* __VIR_STRING_H__ */
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
index 9d0b438..38d0126 100644
--- a/tests/virstringtest.c
+++ b/tests/virstringtest.c
@@ -551,6 +551,29 @@ static int testStripIPv6Brackets(const void *args)
return ret;
}
+static int testStripControlChars(const void *args)
+{
+ const struct testStripData *data = args;
+ int ret = -1;
+ char *res = NULL;
+
+ if (VIR_STRDUP(res, data->string) < 0)
+ goto cleanup;
+
+ virStringStripControlChars(res);
+
+ if (STRNEQ_NULLABLE(res, data->result)) {
+ fprintf(stderr, "Returned '%s', expected '%s'\n",
+ NULLSTR(res), NULLSTR(data->result));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(res);
+ return ret;
+}
static int
mymain(void)
@@ -783,6 +806,22 @@ mymain(void)
TEST_STRIP_IPV6_BRACKETS(":hello]", ":hello]");
TEST_STRIP_IPV6_BRACKETS(":[]:", ":[]:");
+#define TEST_STRIP_CONTROL_CHARS(str, res) \
+ do { \
+ struct testStripData stripData = { \
+ .string = str, \
+ .result = res, \
+ }; \
+ if (virtTestRun("Strip control chars from " #str, \
+ testStripControlChars, &stripData) < 0) \
+ ret = -1; \
+ } while (0)
+
+ TEST_STRIP_CONTROL_CHARS(NULL, NULL);
+ TEST_STRIP_CONTROL_CHARS("\nhello \r hello\t", "\nhello \r
hello\t");
+ TEST_STRIP_CONTROL_CHARS("\x01H\x02" "E\x03L\x04L\x05O",
"HELLO");
+ TEST_STRIP_CONTROL_CHARS("\x01\x02\x03\x04HELL\x05O", "HELLO");
+ TEST_STRIP_CONTROL_CHARS("\nhello \x01\x07hello\t", "\nhello
hello\t");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
2.0.5