mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
7c9a2d88cd
The source code base needs to be adapted as well. Some files include virutil.h just for the string related functions (here, the include is substituted to match the new file), some include virutil.h without any need (here, the include is removed), and some require both.
221 lines
6.1 KiB
C
221 lines
6.1 KiB
C
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "internal.h"
|
|
#include "testutils.h"
|
|
#include "virbuffer.h"
|
|
#include "viralloc.h"
|
|
#include "virstring.h"
|
|
|
|
#define TEST_ERROR(...) \
|
|
do { \
|
|
if (virTestGetDebug()) \
|
|
fprintf(stderr, __VA_ARGS__); \
|
|
} while (0)
|
|
|
|
struct testInfo {
|
|
int doEscape;
|
|
};
|
|
|
|
static int testBufInfiniteLoop(const void *data)
|
|
{
|
|
virBuffer bufinit = VIR_BUFFER_INITIALIZER;
|
|
virBufferPtr buf = &bufinit;
|
|
char *addstr = NULL, *bufret = NULL;
|
|
int ret = -1;
|
|
const struct testInfo *info = data;
|
|
|
|
virBufferAddChar(buf, 'a');
|
|
|
|
/*
|
|
* Infinite loop used to trigger if:
|
|
* (strlen + 1 > 1000) && (strlen == buf-size - buf-use - 1)
|
|
* which was the case after the above addchar at the time of the bug.
|
|
* This test is a bit fragile, since it relies on virBuffer internals.
|
|
*/
|
|
if (virAsprintf(&addstr, "%*s", buf->a - buf->b - 1, "a") < 0) {
|
|
goto out;
|
|
}
|
|
|
|
if (info->doEscape)
|
|
virBufferEscapeString(buf, "%s", addstr);
|
|
else
|
|
virBufferAsprintf(buf, "%s", addstr);
|
|
|
|
ret = 0;
|
|
out:
|
|
bufret = virBufferContentAndReset(buf);
|
|
if (!bufret) {
|
|
TEST_ERROR("Buffer had error set");
|
|
ret = -1;
|
|
}
|
|
|
|
VIR_FREE(addstr);
|
|
VIR_FREE(bufret);
|
|
return ret;
|
|
}
|
|
|
|
static int testBufAutoIndent(const void *data ATTRIBUTE_UNUSED)
|
|
{
|
|
virBuffer bufinit = VIR_BUFFER_INITIALIZER;
|
|
virBufferPtr buf = &bufinit;
|
|
const char expected[] =
|
|
" 1\n 2\n 3\n 4\n 5\n 6\n 7\n &\n 8\n 9\n 10\n ' 11'\n";
|
|
char *result = NULL;
|
|
int ret = 0;
|
|
|
|
if (virBufferGetIndent(buf, false) != 0 ||
|
|
virBufferGetIndent(buf, true) != 0) {
|
|
TEST_ERROR("Wrong indentation");
|
|
ret = -1;
|
|
}
|
|
virBufferAdjustIndent(buf, 3);
|
|
if (STRNEQ(virBufferCurrentContent(buf), "")) {
|
|
TEST_ERROR("Wrong content");
|
|
ret = -1;
|
|
}
|
|
if (virBufferGetIndent(buf, false) != 3 ||
|
|
virBufferGetIndent(buf, true) != 3 ||
|
|
virBufferError(buf)) {
|
|
TEST_ERROR("Wrong indentation");
|
|
ret = -1;
|
|
}
|
|
virBufferAdjustIndent(buf, -2);
|
|
if (virBufferGetIndent(buf, false) != 1 ||
|
|
virBufferGetIndent(buf, true) != 1 ||
|
|
virBufferError(buf)) {
|
|
TEST_ERROR("Wrong indentation");
|
|
ret = -1;
|
|
}
|
|
virBufferAdjustIndent(buf, -3);
|
|
if (virBufferGetIndent(buf, false) != -1 ||
|
|
virBufferGetIndent(buf, true) != -1 ||
|
|
virBufferError(buf) != -1) {
|
|
TEST_ERROR("Usage error not flagged");
|
|
ret = -1;
|
|
}
|
|
virBufferFreeAndReset(buf);
|
|
if (virBufferGetIndent(buf, false) != 0 ||
|
|
virBufferGetIndent(buf, true) != 0 ||
|
|
virBufferError(buf)) {
|
|
TEST_ERROR("Reset didn't clear indentation");
|
|
ret = -1;
|
|
}
|
|
virBufferAdjustIndent(buf, 2);
|
|
virBufferAddLit(buf, "1");
|
|
if (STRNEQ(virBufferCurrentContent(buf), " 1")) {
|
|
TEST_ERROR("Wrong content");
|
|
ret = -1;
|
|
}
|
|
if (virBufferGetIndent(buf, false) != 2 ||
|
|
virBufferGetIndent(buf, true) != 0) {
|
|
TEST_ERROR("Wrong indentation");
|
|
ret = -1;
|
|
}
|
|
virBufferAddLit(buf, "\n");
|
|
virBufferAdd(buf, "" "2\n", -1); /* Extra "" appeases syntax-check */
|
|
virBufferAddChar(buf, '3');
|
|
virBufferAddChar(buf, '\n');
|
|
virBufferAsprintf(buf, "%d", 4);
|
|
virBufferAsprintf(buf, "%c", '\n');
|
|
virBufferStrcat(buf, "5", "\n", "6\n", NULL);
|
|
virBufferEscapeString(buf, "%s\n", "7");
|
|
virBufferEscapeString(buf, "%s\n", "&");
|
|
virBufferEscapeSexpr(buf, "%s", "8\n");
|
|
virBufferURIEncodeString(buf, "9");
|
|
virBufferAddChar(buf, '\n');
|
|
virBufferEscapeShell(buf, "10");
|
|
virBufferAddChar(buf, '\n');
|
|
virBufferEscapeShell(buf, " 11");
|
|
virBufferAddChar(buf, '\n');
|
|
|
|
result = virBufferContentAndReset(buf);
|
|
if (!result || STRNEQ(result, expected)) {
|
|
virtTestDifference(stderr, expected, result);
|
|
ret = -1;
|
|
}
|
|
VIR_FREE(result);
|
|
return ret;
|
|
}
|
|
|
|
static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
|
|
{
|
|
virBuffer bufinit = VIR_BUFFER_INITIALIZER;
|
|
virBufferPtr buf = NULL;
|
|
char *result = NULL;
|
|
const char *expected = "a,b";
|
|
int ret = -1;
|
|
int i = 1;
|
|
|
|
#define ACT(str, len, result) \
|
|
do { \
|
|
if (virBufferTrim(buf, str, len) != result) { \
|
|
TEST_ERROR("trim %d failed", i); \
|
|
goto cleanup; \
|
|
} \
|
|
i++; \
|
|
} while (0);
|
|
|
|
if (virBufferTrim(buf, "", 0) != -1) {
|
|
TEST_ERROR("Wrong failure detection 1");
|
|
goto cleanup;
|
|
}
|
|
buf = &bufinit;
|
|
if (virBufferTrim(buf, NULL, -1) != -1) {
|
|
TEST_ERROR("Wrong failure detection 2");
|
|
goto cleanup;
|
|
}
|
|
|
|
virBufferAddLit(buf, "a;");
|
|
ACT("", 0, 1);
|
|
ACT("", -1, 1);
|
|
ACT(NULL, 1, 1);
|
|
ACT(NULL, 5, 0);
|
|
ACT("a", 2, 0);
|
|
|
|
virBufferAddLit(buf, ",b,,");
|
|
ACT("b", -1, 0);
|
|
ACT("b,,", 1, 1);
|
|
ACT(",", -1, 1);
|
|
|
|
result = virBufferContentAndReset(buf);
|
|
if (!result || STRNEQ(result, expected)) {
|
|
virtTestDifference(stderr, expected, result);
|
|
goto cleanup;
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
virBufferFreeAndReset(buf);
|
|
VIR_FREE(result);
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int
|
|
mymain(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
|
|
#define DO_TEST(msg, cb, data) \
|
|
do { \
|
|
struct testInfo info = { data }; \
|
|
if (virtTestRun("Buf: " msg, 1, cb, &info) < 0) \
|
|
ret = -1; \
|
|
} while (0)
|
|
|
|
DO_TEST("EscapeString infinite loop", testBufInfiniteLoop, 1);
|
|
DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
|
|
DO_TEST("Auto-indentation", testBufAutoIndent, 0);
|
|
DO_TEST("Trim", testBufTrim, 0);
|
|
|
|
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
}
|
|
|
|
VIRT_TEST_MAIN(mymain)
|