From 0918b84968ab8aeb1dc17d5da839d68d947f478f Mon Sep 17 00:00:00 2001 From: Pavel Hrdina Date: Fri, 12 May 2017 14:26:09 +0200 Subject: [PATCH] util: introduce virBufferEscapeRegex Add a helper to escape all possible meta-characters used for POSIX extended regular expressions. Signed-off-by: Pavel Hrdina --- src/libvirt_private.syms | 1 + src/util/virbuffer.c | 19 +++++++++++++++++++ src/util/virbuffer.h | 3 +++ tests/virbuftest.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d32c6e7549..bbe283529b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1312,6 +1312,7 @@ virBufferCurrentContent; virBufferError; virBufferEscape; virBufferEscapeN; +virBufferEscapeRegex; virBufferEscapeSexpr; virBufferEscapeShell; virBufferEscapeString; diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c index 80c8e289d4..f07b119c0f 100644 --- a/src/util/virbuffer.c +++ b/src/util/virbuffer.c @@ -555,6 +555,25 @@ virBufferEscapeSexpr(virBufferPtr buf, virBufferEscape(buf, '\\', "\\'", format, str); } +/** + * virBufferEscapeRegex: + * @buf: the buffer to append to + * @format: a printf like format string but with only one %s parameter + * @str: the string argument which needs to be escaped + * + * Do a formatted print with a single string to a buffer. The @str is + * escaped to avoid using POSIX extended regular expression meta-characters. + * Escaping is not applied to characters specified in @format. Auto + * indentation may be applied. + */ +void +virBufferEscapeRegex(virBufferPtr buf, + const char *format, + const char *str) +{ + virBufferEscape(buf, '\\', "^$.|?*+()[]{}\\", format, str); +} + /** * virBufferEscape: * @buf: the buffer to append to diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h index d1b64ca3a3..7a7014aa70 100644 --- a/src/util/virbuffer.h +++ b/src/util/virbuffer.h @@ -88,6 +88,9 @@ void virBufferEscapeString(virBufferPtr buf, const char *format, const char *str); void virBufferEscapeSexpr(virBufferPtr buf, const char *format, const char *str); +void virBufferEscapeRegex(virBufferPtr buf, + const char *format, + const char *str); void virBufferEscapeShell(virBufferPtr buf, const char *str); void virBufferURIEncodeString(virBufferPtr buf, const char *str); diff --git a/tests/virbuftest.c b/tests/virbuftest.c index 5905fee7d4..940e4c1c61 100644 --- a/tests/virbuftest.c +++ b/tests/virbuftest.c @@ -404,6 +404,35 @@ testBufEscapeN(const void *opaque) } +static int +testBufEscapeRegex(const void *opaque) +{ + const struct testBufAddStrData *data = opaque; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *actual; + int ret = -1; + + virBufferEscapeRegex(&buf, "%s", data->data); + + if (!(actual = virBufferContentAndReset(&buf))) { + VIR_TEST_DEBUG("testBufEscapeN: buf is empty"); + goto cleanup; + } + + if (STRNEQ_NULLABLE(actual, data->expect)) { + VIR_TEST_DEBUG("testBufEscapeN: Strings don't match:\n"); + virTestDifference(stderr, data->expect, actual); + goto cleanup; + } + + ret = 0; + + cleanup: + VIR_FREE(actual); + return ret; +} + + static int testBufSetIndent(const void *opaque ATTRIBUTE_UNUSED) { @@ -492,6 +521,17 @@ mymain(void) DO_TEST_ESCAPEN("equal=escape", "equal\\=escape"); DO_TEST_ESCAPEN("comma,equal=escape", "comma,,equal\\=escape"); +#define DO_TEST_ESCAPE_REGEX(data, expect) \ + do { \ + struct testBufAddStrData info = { data, expect }; \ + if (virTestRun("Buf: EscapeRegex", testBufEscapeRegex, &info) < 0) \ + ret = -1; \ + } while (0) + + DO_TEST_ESCAPE_REGEX("noescape", "noescape"); + DO_TEST_ESCAPE_REGEX("^$.|?*+()[]{}\\", + "\\^\\$\\.\\|\\?\\*\\+\\(\\)\\[\\]\\{\\}\\\\"); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }