diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 18d0f2adfe..6662c8dac1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2755,6 +2755,7 @@ virStrcpy; virStrdup; virStringBufferIsPrintable; virStringEncodeBase64; +virStringFilterChars; virStringHasChars; virStringHasControlChars; virStringIsEmpty; diff --git a/src/util/virstring.c b/src/util/virstring.c index 0cb06bdc9d..1c58df9150 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -1293,6 +1293,30 @@ virStringStripControlChars(char *str) str[j] = '\0'; } +/** + * virStringFilterChars: + * @str: the string to strip + * @valid: the valid characters for the string + * + * Modify the string in-place to remove the characters that aren't + * in the list of valid ones. + */ +void +virStringFilterChars(char *str, const char *valid) +{ + size_t len, i, j; + + if (!str) + return; + + len = strlen(str); + for (i = 0, j = 0; i < len; i++) { + if (strchr(valid, str[i])) + str[j++] = str[i]; + } + str[j] = '\0'; +} + /** * virStringToUpper: * @str: string to capitalize diff --git a/src/util/virstring.h b/src/util/virstring.h index b19abaf9fa..8af054bce7 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -293,6 +293,7 @@ bool virStringHasChars(const char *str, const char *chars); bool virStringHasControlChars(const char *str); void virStringStripControlChars(char *str); +void virStringFilterChars(char *str, const char *valid); bool virStringIsPrintable(const char *str); bool virStringBufferIsPrintable(const uint8_t *buf, size_t buflen); diff --git a/tests/virstringtest.c b/tests/virstringtest.c index 320f7a3983..e8518ede18 100644 --- a/tests/virstringtest.c +++ b/tests/virstringtest.c @@ -767,6 +767,36 @@ static int testStripControlChars(const void *args) return ret; } +struct testFilterData { + const char *string; + const char *valid; + const char *result; +}; + +static int testFilterChars(const void *args) +{ + const struct testFilterData *data = args; + int ret = -1; + char *res = NULL; + + if (VIR_STRDUP(res, data->string) < 0) + goto cleanup; + + virStringFilterChars(res, data->valid); + + 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) { @@ -1085,6 +1115,22 @@ mymain(void) 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"); + +#define TEST_FILTER_CHARS(str, filter, res) \ + do { \ + struct testFilterData filterData = { \ + .string = str, \ + .valid = filter, \ + .result = res, \ + }; \ + if (virTestRun("Filter chars from " #str, \ + testFilterChars, &filterData) < 0) \ + ret = -1; \ + } while (0) + + TEST_FILTER_CHARS(NULL, NULL, NULL); + TEST_FILTER_CHARS("hello 123 hello", "helo", "hellohello"); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }