diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:08 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:47:08 +0000 |
commit | 29b5ab554790bb57337a3b6ab9dcd963cf69d22e (patch) | |
tree | be1456d2bc6c1fb078695fad7bc8f6b212062d3c /tests/util/str | |
parent | Initial commit. (diff) | |
download | libgit2-29b5ab554790bb57337a3b6ab9dcd963cf69d22e.tar.xz libgit2-29b5ab554790bb57337a3b6ab9dcd963cf69d22e.zip |
Adding upstream version 1.7.2+ds.upstream/1.7.2+ds
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/util/str')
-rw-r--r-- | tests/util/str/basic.c | 50 | ||||
-rw-r--r-- | tests/util/str/oom.c | 71 | ||||
-rw-r--r-- | tests/util/str/percent.c | 48 | ||||
-rw-r--r-- | tests/util/str/quote.c | 87 | ||||
-rw-r--r-- | tests/util/str/splice.c | 92 |
5 files changed, 348 insertions, 0 deletions
diff --git a/tests/util/str/basic.c b/tests/util/str/basic.c new file mode 100644 index 0000000..5d25568 --- /dev/null +++ b/tests/util/str/basic.c @@ -0,0 +1,50 @@ +#include "clar_libgit2.h" + +static const char *test_string = "Have you seen that? Have you seeeen that??"; + +void test_str_basic__resize(void) +{ + git_str buf1 = GIT_STR_INIT; + git_str_puts(&buf1, test_string); + cl_assert(git_str_oom(&buf1) == 0); + cl_assert_equal_s(git_str_cstr(&buf1), test_string); + + git_str_puts(&buf1, test_string); + cl_assert(strlen(git_str_cstr(&buf1)) == strlen(test_string) * 2); + git_str_dispose(&buf1); +} + +void test_str_basic__resize_incremental(void) +{ + git_str buf1 = GIT_STR_INIT; + + /* Presently, asking for 6 bytes will round up to 8. */ + cl_git_pass(git_str_puts(&buf1, "Hello")); + cl_assert_equal_i(5, buf1.size); + cl_assert_equal_i(8, buf1.asize); + + /* Ensure an additional byte does not realloc. */ + cl_git_pass(git_str_grow_by(&buf1, 1)); + cl_assert_equal_i(5, buf1.size); + cl_assert_equal_i(8, buf1.asize); + + /* But requesting many does. */ + cl_git_pass(git_str_grow_by(&buf1, 16)); + cl_assert_equal_i(5, buf1.size); + cl_assert(buf1.asize > 8); + + git_str_dispose(&buf1); +} + +void test_str_basic__printf(void) +{ + git_str buf2 = GIT_STR_INIT; + git_str_printf(&buf2, "%s %s %d ", "shoop", "da", 23); + cl_assert(git_str_oom(&buf2) == 0); + cl_assert_equal_s(git_str_cstr(&buf2), "shoop da 23 "); + + git_str_printf(&buf2, "%s %d", "woop", 42); + cl_assert(git_str_oom(&buf2) == 0); + cl_assert_equal_s(git_str_cstr(&buf2), "shoop da 23 woop 42"); + git_str_dispose(&buf2); +} diff --git a/tests/util/str/oom.c b/tests/util/str/oom.c new file mode 100644 index 0000000..810c1f2 --- /dev/null +++ b/tests/util/str/oom.c @@ -0,0 +1,71 @@ +#include "clar_libgit2.h" +#include "clar_libgit2_alloc.h" + +/* Override default allocators with ones that will fail predictably. */ + +static git_allocator std_alloc; +static git_allocator oom_alloc; + +static void *oom_malloc(size_t n, const char *file, int line) +{ + /* Reject any allocation of more than 100 bytes */ + return (n > 100) ? NULL : std_alloc.gmalloc(n, file, line); +} + +static void *oom_realloc(void *p, size_t n, const char *file, int line) +{ + /* Reject any allocation of more than 100 bytes */ + return (n > 100) ? NULL : std_alloc.grealloc(p, n, file, line); +} + +void test_str_oom__initialize(void) +{ + git_stdalloc_init_allocator(&std_alloc); + git_stdalloc_init_allocator(&oom_alloc); + + oom_alloc.gmalloc = oom_malloc; + oom_alloc.grealloc = oom_realloc; + + cl_git_pass(git_allocator_setup(&oom_alloc)); +} + +void test_str_oom__cleanup(void) +{ + cl_git_pass(git_allocator_setup(NULL)); +} + +void test_str_oom__grow(void) +{ + git_str buf = GIT_STR_INIT; + + cl_git_pass(git_str_grow(&buf, 42)); + cl_assert(!git_str_oom(&buf)); + + cl_assert(git_str_grow(&buf, 101) == -1); + cl_assert(git_str_oom(&buf)); + + git_str_dispose(&buf); +} + +void test_str_oom__grow_by(void) +{ + git_str buf = GIT_STR_INIT; + + cl_git_pass(git_str_grow_by(&buf, 42)); + cl_assert(!git_str_oom(&buf)); + + cl_assert(git_str_grow_by(&buf, 101) == -1); + cl_assert(git_str_oom(&buf)); +} + +void test_str_oom__allocation_failure(void) +{ + git_str buf = GIT_STR_INIT; + + cl_alloc_limit(10); + + cl_git_pass(git_str_puts(&buf, "foobar")); + cl_git_fail(git_str_puts(&buf, "foobar")); + + cl_alloc_reset(); +} diff --git a/tests/util/str/percent.c b/tests/util/str/percent.c new file mode 100644 index 0000000..3393890 --- /dev/null +++ b/tests/util/str/percent.c @@ -0,0 +1,48 @@ +#include "clar_libgit2.h" + +static void expect_decode_pass(const char *expected, const char *encoded) +{ + git_str in = GIT_STR_INIT, out = GIT_STR_INIT; + + /* + * ensure that we only read the given length of the input buffer + * by putting garbage at the end. this will ensure that we do + * not, eg, rely on nul-termination or walk off the end of the buf. + */ + cl_git_pass(git_str_puts(&in, encoded)); + cl_git_pass(git_str_PUTS(&in, "TRAILER")); + + cl_git_pass(git_str_decode_percent(&out, in.ptr, strlen(encoded))); + + cl_assert_equal_s(expected, git_str_cstr(&out)); + cl_assert_equal_i(strlen(expected), git_str_len(&out)); + + git_str_dispose(&in); + git_str_dispose(&out); +} + +void test_str_percent__decode_succeeds(void) +{ + expect_decode_pass("", ""); + expect_decode_pass(" ", "%20"); + expect_decode_pass("a", "a"); + expect_decode_pass(" a", "%20a"); + expect_decode_pass("a ", "a%20"); + expect_decode_pass("github.com", "github.com"); + expect_decode_pass("github.com", "githu%62.com"); + expect_decode_pass("github.com", "github%2ecom"); + expect_decode_pass("foo bar baz", "foo%20bar%20baz"); + expect_decode_pass("foo bar baz", "foo%20bar%20baz"); + expect_decode_pass("foo bar ", "foo%20bar%20"); +} + +void test_str_percent__ignores_invalid(void) +{ + expect_decode_pass("githu%%.com", "githu%%.com"); + expect_decode_pass("github.co%2", "github.co%2"); + expect_decode_pass("github%2.com", "github%2.com"); + expect_decode_pass("githu%2z.com", "githu%2z.com"); + expect_decode_pass("github.co%9z", "github.co%9z"); + expect_decode_pass("github.co%2", "github.co%2"); + expect_decode_pass("github.co%", "github.co%"); +} diff --git a/tests/util/str/quote.c b/tests/util/str/quote.c new file mode 100644 index 0000000..2c65462 --- /dev/null +++ b/tests/util/str/quote.c @@ -0,0 +1,87 @@ +#include "clar_libgit2.h" + +static void expect_quote_pass(const char *expected, const char *str) +{ + git_str buf = GIT_STR_INIT; + + cl_git_pass(git_str_puts(&buf, str)); + cl_git_pass(git_str_quote(&buf)); + + cl_assert_equal_s(expected, git_str_cstr(&buf)); + cl_assert_equal_i(strlen(expected), git_str_len(&buf)); + + git_str_dispose(&buf); +} + +void test_str_quote__quote_succeeds(void) +{ + expect_quote_pass("", ""); + expect_quote_pass("foo", "foo"); + expect_quote_pass("foo/bar/baz.c", "foo/bar/baz.c"); + expect_quote_pass("foo bar", "foo bar"); + expect_quote_pass("\"\\\"leading quote\"", "\"leading quote"); + expect_quote_pass("\"slash\\\\y\"", "slash\\y"); + expect_quote_pass("\"foo\\r\\nbar\"", "foo\r\nbar"); + expect_quote_pass("\"foo\\177bar\"", "foo\177bar"); + expect_quote_pass("\"foo\\001bar\"", "foo\001bar"); + expect_quote_pass("\"foo\\377bar\"", "foo\377bar"); +} + +static void expect_unquote_pass(const char *expected, const char *quoted) +{ + git_str buf = GIT_STR_INIT; + + cl_git_pass(git_str_puts(&buf, quoted)); + cl_git_pass(git_str_unquote(&buf)); + + cl_assert_equal_s(expected, git_str_cstr(&buf)); + cl_assert_equal_i(strlen(expected), git_str_len(&buf)); + + git_str_dispose(&buf); +} + +static void expect_unquote_fail(const char *quoted) +{ + git_str buf = GIT_STR_INIT; + + cl_git_pass(git_str_puts(&buf, quoted)); + cl_git_fail(git_str_unquote(&buf)); + + git_str_dispose(&buf); +} + +void test_str_quote__unquote_succeeds(void) +{ + expect_unquote_pass("", "\"\""); + expect_unquote_pass(" ", "\" \""); + expect_unquote_pass("foo", "\"foo\""); + expect_unquote_pass("foo bar", "\"foo bar\""); + expect_unquote_pass("foo\"bar", "\"foo\\\"bar\""); + expect_unquote_pass("foo\\bar", "\"foo\\\\bar\""); + expect_unquote_pass("foo\tbar", "\"foo\\tbar\""); + expect_unquote_pass("\vfoo\tbar\n", "\"\\vfoo\\tbar\\n\""); + expect_unquote_pass("foo\nbar", "\"foo\\012bar\""); + expect_unquote_pass("foo\r\nbar", "\"foo\\015\\012bar\""); + expect_unquote_pass("foo\r\nbar", "\"\\146\\157\\157\\015\\012\\142\\141\\162\""); + expect_unquote_pass("newline: \n", "\"newline: \\012\""); + expect_unquote_pass("0xff: \377", "\"0xff: \\377\""); +} + +void test_str_quote__unquote_fails(void) +{ + expect_unquote_fail("no quotes at all"); + expect_unquote_fail("\"no trailing quote"); + expect_unquote_fail("no leading quote\""); + expect_unquote_fail("\"invalid \\z escape char\""); + expect_unquote_fail("\"\\q invalid escape char\""); + expect_unquote_fail("\"invalid escape char \\p\""); + expect_unquote_fail("\"invalid \\1 escape char \""); + expect_unquote_fail("\"invalid \\14 escape char \""); + expect_unquote_fail("\"invalid \\280 escape char\""); + expect_unquote_fail("\"invalid \\378 escape char\""); + expect_unquote_fail("\"invalid \\380 escape char\""); + expect_unquote_fail("\"invalid \\411 escape char\""); + expect_unquote_fail("\"truncated escape char \\\""); + expect_unquote_fail("\"truncated escape char \\0\""); + expect_unquote_fail("\"truncated escape char \\01\""); +} diff --git a/tests/util/str/splice.c b/tests/util/str/splice.c new file mode 100644 index 0000000..14e844e --- /dev/null +++ b/tests/util/str/splice.c @@ -0,0 +1,92 @@ +#include "clar_libgit2.h" + +static git_str _buf; + +void test_str_splice__initialize(void) { + git_str_init(&_buf, 16); +} + +void test_str_splice__cleanup(void) { + git_str_dispose(&_buf); +} + +void test_str_splice__preprend(void) +{ + git_str_sets(&_buf, "world!"); + + cl_git_pass(git_str_splice(&_buf, 0, 0, "Hello Dolly", strlen("Hello "))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__append(void) +{ + git_str_sets(&_buf, "Hello"); + + cl_git_pass(git_str_splice(&_buf, git_str_len(&_buf), 0, " world!", strlen(" world!"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__insert_at(void) +{ + git_str_sets(&_buf, "Hell world!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hell"), 0, "o", strlen("o"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__remove_at(void) +{ + git_str_sets(&_buf, "Hello world of warcraft!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hello world"), strlen(" of warcraft"), "", 0)); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__replace(void) +{ + git_str_sets(&_buf, "Hell0 w0rld!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hell"), strlen("0 w0"), "o wo", strlen("o wo"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__replace_with_longer(void) +{ + git_str_sets(&_buf, "Hello you!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hello "), strlen("you"), "world", strlen("world"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__replace_with_shorter(void) +{ + git_str_sets(&_buf, "Brave new world!"); + + cl_git_pass(git_str_splice(&_buf, 0, strlen("Brave new"), "Hello", strlen("Hello"))); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__truncate(void) +{ + git_str_sets(&_buf, "Hello world!!"); + + cl_git_pass(git_str_splice(&_buf, strlen("Hello world!"), strlen("!"), "", 0)); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} + +void test_str_splice__dont_do_anything(void) +{ + git_str_sets(&_buf, "Hello world!"); + + cl_git_pass(git_str_splice(&_buf, 3, 0, "Hello", 0)); + + cl_assert_equal_s("Hello world!", git_str_cstr(&_buf)); +} |