diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/test-bitmap.c | 105 | ||||
-rw-r--r-- | src/test/test-btrfs.c | 2 | ||||
-rw-r--r-- | src/test/test-copy.c | 10 | ||||
-rw-r--r-- | src/test/test-dns-domain.c | 74 | ||||
-rw-r--r-- | src/test/test-fileio.c | 24 | ||||
-rw-r--r-- | src/test/test-pty.c | 2 | ||||
-rw-r--r-- | src/test/test-util.c | 331 |
7 files changed, 525 insertions, 23 deletions
diff --git a/src/test/test-bitmap.c b/src/test/test-bitmap.c new file mode 100644 index 0000000000..96deeded7e --- /dev/null +++ b/src/test/test-bitmap.c @@ -0,0 +1,105 @@ +/*** + This file is part of systemd + + Copyright 2015 Tom Gundersen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "bitmap.h" + +int main(int argc, const char *argv[]) { + _cleanup_bitmap_free_ Bitmap *b = NULL; + Iterator it; + unsigned n = (unsigned) -1, i = 0; + + b = bitmap_new(); + assert_se(b); + + assert_se(bitmap_ensure_allocated(&b) == 0); + bitmap_free(b); + b = NULL; + assert_se(bitmap_ensure_allocated(&b) == 0); + + assert_se(bitmap_isset(b, 0) == false); + assert_se(bitmap_isset(b, 1) == false); + assert_se(bitmap_isset(b, 256) == false); + assert_se(bitmap_isclear(b) == true); + + assert_se(bitmap_set(b, 0) == 0); + assert_se(bitmap_isset(b, 0) == true); + assert_se(bitmap_isclear(b) == false); + bitmap_unset(b, 0); + assert_se(bitmap_isset(b, 0) == false); + assert_se(bitmap_isclear(b) == true); + + assert_se(bitmap_set(b, 1) == 0); + assert_se(bitmap_isset(b, 1) == true); + assert_se(bitmap_isclear(b) == false); + bitmap_unset(b, 1); + assert_se(bitmap_isset(b, 1) == false); + assert_se(bitmap_isclear(b) == true); + + assert_se(bitmap_set(b, 256) == 0); + assert_se(bitmap_isset(b, 256) == true); + assert_se(bitmap_isclear(b) == false); + bitmap_unset(b, 256); + assert_se(bitmap_isset(b, 256) == false); + assert_se(bitmap_isclear(b) == true); + + assert_se(bitmap_set(b, 32) == 0); + bitmap_unset(b, 0); + assert_se(bitmap_isset(b, 32) == true); + bitmap_unset(b, 32); + + BITMAP_FOREACH(n, NULL, it) + assert_not_reached("NULL bitmap"); + + assert_se(bitmap_set(b, 0) == 0); + assert_se(bitmap_set(b, 1) == 0); + assert_se(bitmap_set(b, 256) == 0); + + BITMAP_FOREACH(n, b, it) { + assert_se(n == i); + if (i == 0) + i = 1; + else if (i == 1) + i = 256; + else if (i == 256) + i = (unsigned) -1; + } + + assert_se(i == (unsigned) -1); + + i = 0; + + BITMAP_FOREACH(n, b, it) { + assert_se(n == i); + if (i == 0) + i = 1; + else if (i == 1) + i = 256; + else if (i == 256) + i = (unsigned) -1; + } + + assert_se(i == (unsigned) -1); + + bitmap_clear(b); + assert_se(bitmap_isclear(b) == true); + + assert_se(bitmap_set(b, (unsigned) -1) == -ERANGE); + + return 0; +} diff --git a/src/test/test-btrfs.c b/src/test/test-btrfs.c index 838ffcba3d..e4771c9dd7 100644 --- a/src/test/test-btrfs.c +++ b/src/test/test-btrfs.c @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) { if (r < 0) log_error_errno(r, "Failed to make subvolume: %m"); - r = write_string_file("/xxxtest/afile", "ljsadhfljasdkfhlkjdsfha"); + r = write_string_file("/xxxtest/afile", "ljsadhfljasdkfhlkjdsfha", WRITE_STRING_FILE_CREATE); if (r < 0) log_error_errno(r, "Failed to write file: %m"); diff --git a/src/test/test-copy.c b/src/test/test-copy.c index e55ffaa16a..b73c958ec5 100644 --- a/src/test/test-copy.c +++ b/src/test/test-copy.c @@ -43,7 +43,7 @@ static void test_copy_file(void) { assert_se(fd >= 0); close(fd); - assert_se(write_string_file(fn, "foo bar bar bar foo") == 0); + assert_se(write_string_file(fn, "foo bar bar bar foo", WRITE_STRING_FILE_CREATE) == 0); assert_se(copy_file(fn, fn_copy, 0, 0644, 0) == 0); @@ -67,7 +67,7 @@ static void test_copy_file_fd(void) { out_fd = mkostemp_safe(out_fn, O_RDWR); assert_se(out_fd >= 0); - assert_se(write_string_file(in_fn, text) == 0); + assert_se(write_string_file(in_fn, text, WRITE_STRING_FILE_CREATE) == 0); assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd, true) < 0); assert_se(copy_file_fd(in_fn, out_fd, true) >= 0); assert_se(lseek(out_fd, SEEK_SET, 0) == 0); @@ -94,7 +94,7 @@ static void test_copy_tree(void) { char *f = strjoina(original_dir, *p); assert_se(mkdir_parents(f, 0755) >= 0); - assert_se(write_string_file(f, "file") == 0); + assert_se(write_string_file(f, "file", WRITE_STRING_FILE_CREATE) == 0); } STRV_FOREACH_PAIR(link, p, links) { @@ -139,7 +139,9 @@ static void test_copy_bytes(void) { int r, r2; char buf[1024], buf2[1024]; - infd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); + infd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC); + if (infd < 0) + infd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); assert_se(infd >= 0); assert_se(pipe2(pipefd, O_CLOEXEC) == 0); diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c index 527cdd3b54..31e110cf0d 100644 --- a/src/test/test-dns-domain.c +++ b/src/test/test-dns-domain.c @@ -50,6 +50,46 @@ static void test_dns_label_unescape(void) { test_dns_label_unescape_one("foobar.", "foobar", 20, 6); } +static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) { + char buffer[buffer_sz]; + const char *label; + int r; + + label = what + strlen(what); + + r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz); + assert_se(r == ret1); + if (r >= 0) + assert_se(streq(buffer, expect1)); + + r = dns_label_unescape_suffix(what, &label, buffer, buffer_sz); + assert_se(r == ret2); + if (r >= 0) + assert_se(streq(buffer, expect2)); +} + +static void test_dns_label_unescape_suffix(void) { + test_dns_label_unescape_suffix_one("hallo", "hallo", "", 6, 5, 0); + test_dns_label_unescape_suffix_one("hallo", "hallo", "", 4, -ENOSPC, -ENOSPC); + test_dns_label_unescape_suffix_one("", "", "", 10, 0, 0); + test_dns_label_unescape_suffix_one("hallo\\.foobar", "hallo.foobar", "", 20, 12, 0); + test_dns_label_unescape_suffix_one("hallo.foobar", "foobar", "hallo", 10, 6, 5); + test_dns_label_unescape_suffix_one("hallo.foobar\n", "foobar", "foobar", 20, -EINVAL, -EINVAL); + test_dns_label_unescape_suffix_one("hallo\\", "hallo", "hallo", 20, -EINVAL, -EINVAL); + test_dns_label_unescape_suffix_one("hallo\\032 ", "hallo ", "", 20, 7, 0); + test_dns_label_unescape_suffix_one(".", "", "", 20, 0, 0); + test_dns_label_unescape_suffix_one("..", "", "", 20, 0, 0); + test_dns_label_unescape_suffix_one(".foobar", "foobar", "", 20, 6, -EINVAL); + test_dns_label_unescape_suffix_one("foobar.", "", "foobar", 20, 0, 6); + test_dns_label_unescape_suffix_one("foo\\\\bar", "foo\\bar", "", 20, 7, 0); + test_dns_label_unescape_suffix_one("foo.bar", "bar", "foo", 20, 3, 3); + test_dns_label_unescape_suffix_one("foo..bar", "bar", "", 20, 3, -EINVAL); + test_dns_label_unescape_suffix_one("foo...bar", "bar", "", 20, 3, -EINVAL); + test_dns_label_unescape_suffix_one("foo\\.bar", "foo.bar", "", 20, 7, 0); + test_dns_label_unescape_suffix_one("foo\\\\.bar", "bar", "foo\\", 20, 3, 4); + test_dns_label_unescape_suffix_one("foo\\\\\\.bar", "foo\\.bar", "", 20, 8, 0); +} + static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) { _cleanup_free_ char *t = NULL; int r; @@ -120,6 +160,38 @@ static void test_dns_name_equal(void) { test_dns_name_equal_one("..", "..", -EINVAL); } +static void test_dns_name_between_one(const char *a, const char *b, const char *c, int ret) { + int r; + + r = dns_name_between(a, b, c); + assert_se(r == ret); + + r = dns_name_between(c, b, a); + if (ret >= 0) + assert_se(r == 0); + else + assert_se(r == ret); +} + +static void test_dns_name_between(void) { + /* see https://tools.ietf.org/html/rfc4034#section-6.1 + Note that we use "\033.z.example" in stead of "\001.z.example" as we + consider the latter invalid */ + test_dns_name_between_one("example", "a.example", "yljkjljk.a.example", true); + test_dns_name_between_one("a.example", "yljkjljk.a.example", "Z.a.example", true); + test_dns_name_between_one("yljkjljk.a.example", "Z.a.example", "zABC.a.EXAMPLE", true); + test_dns_name_between_one("Z.a.example", "zABC.a.EXAMPLE", "z.example", true); + test_dns_name_between_one("zABC.a.EXAMPLE", "z.example", "\\033.z.example", true); + test_dns_name_between_one("z.example", "\\033.z.example", "*.z.example", true); + test_dns_name_between_one("\\033.z.example", "*.z.example", "\\200.z.example", true); + test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true); + test_dns_name_between_one("\\200.z.example", "example", "a.example", true); + + test_dns_name_between_one("example", "a.example", "example", -EINVAL); + test_dns_name_between_one("example", "example", "yljkjljk.a.example", false); + test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false); +} + static void test_dns_name_endswith_one(const char *a, const char *b, int ret) { assert_se(dns_name_endswith(a, b) == ret); } @@ -180,10 +252,12 @@ static void test_dns_name_reverse(void) { int main(int argc, char *argv[]) { test_dns_label_unescape(); + test_dns_label_unescape_suffix(); test_dns_label_escape(); test_dns_name_normalize(); test_dns_name_equal(); test_dns_name_endswith(); + test_dns_name_between(); test_dns_name_root(); test_dns_name_single_label(); test_dns_name_reverse(); diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 4c31b776bd..be3a87958f 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -302,17 +302,27 @@ static void test_write_string_stream(void) { f = fdopen(fd, "r"); assert_se(f); - assert_se(write_string_stream(f, "boohoo") < 0); + assert_se(write_string_stream(f, "boohoo", true) < 0); f = freopen(fn, "r+", f); assert_se(f); - assert_se(write_string_stream(f, "boohoo") == 0); + assert_se(write_string_stream(f, "boohoo", true) == 0); rewind(f); assert_se(fgets(buf, sizeof(buf), f)); assert_se(streq(buf, "boohoo\n")); + f = freopen(fn, "w+", f); + assert_se(f); + + assert_se(write_string_stream(f, "boohoo", false) == 0); + rewind(f); + + assert_se(fgets(buf, sizeof(buf), f)); + printf(">%s<", buf); + assert_se(streq(buf, "boohoo")); + unlink(fn); } @@ -324,7 +334,7 @@ static void test_write_string_file(void) { fd = mkostemp_safe(fn, O_RDWR); assert_se(fd >= 0); - assert_se(write_string_file(fn, "boohoo") == 0); + assert_se(write_string_file(fn, "boohoo", WRITE_STRING_FILE_CREATE) == 0); assert_se(read(fd, buf, sizeof(buf)) == 7); assert_se(streq(buf, "boohoo\n")); @@ -340,8 +350,8 @@ static void test_write_string_file_no_create(void) { fd = mkostemp_safe(fn, O_RDWR); assert_se(fd >= 0); - assert_se(write_string_file_no_create("/a/file/which/does/not/exists/i/guess", "boohoo") < 0); - assert_se(write_string_file_no_create(fn, "boohoo") == 0); + assert_se(write_string_file("/a/file/which/does/not/exists/i/guess", "boohoo", 0) < 0); + assert_se(write_string_file(fn, "boohoo", 0) == 0); assert_se(read(fd, buf, sizeof(buf)) == strlen("boohoo\n")); assert_se(streq(buf, "boohoo\n")); @@ -367,8 +377,8 @@ static void test_load_env_file_pairs(void) { "ANSI_COLOR=\"0;36\"\n" "HOME_URL=\"https://www.archlinux.org/\"\n" "SUPPORT_URL=\"https://bbs.archlinux.org/\"\n" - "BUG_REPORT_URL=\"https://bugs.archlinux.org/\"\n" - ); + "BUG_REPORT_URL=\"https://bugs.archlinux.org/\"\n", + WRITE_STRING_FILE_CREATE); assert_se(r == 0); f = fdopen(fd, "r"); diff --git a/src/test/test-pty.c b/src/test/test-pty.c index 3f97a64ccd..fbab3d4ebe 100644 --- a/src/test/test-pty.c +++ b/src/test/test-pty.c @@ -133,7 +133,7 @@ int main(int argc, char *argv[]) { /* Oh, there're ugly races in the TTY layer regarding HUP vs IN. Turns * out they appear only 10% of the time. I fixed all of them and - * don't see them, anymore. But lets be safe and run this 1000 times + * don't see them, anymore. But let's be safe and run this 1000 times * so we catch any new ones, in case they appear again. */ for (i = 0; i < 1000; ++i) test_pty(); diff --git a/src/test/test-util.c b/src/test/test-util.c index ad9ea3bcce..f43433baa1 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -390,6 +390,39 @@ static void test_unhexchar(void) { assert_se(unhexchar('0') == 0x0); } +static void test_base32hexchar(void) { + assert_se(base32hexchar(0) == '0'); + assert_se(base32hexchar(9) == '9'); + assert_se(base32hexchar(10) == 'A'); + assert_se(base32hexchar(31) == 'V'); +} + +static void test_unbase32hexchar(void) { + assert_se(unbase32hexchar('0') == 0); + assert_se(unbase32hexchar('9') == 9); + assert_se(unbase32hexchar('A') == 10); + assert_se(unbase32hexchar('V') == 31); + assert_se(unbase32hexchar('=') == -EINVAL); +} + +static void test_base64char(void) { + assert_se(base64char(0) == 'A'); + assert_se(base64char(26) == 'a'); + assert_se(base64char(63) == '/'); +} + +static void test_unbase64char(void) { + assert_se(unbase64char('A') == 0); + assert_se(unbase64char('Z') == 25); + assert_se(unbase64char('a') == 26); + assert_se(unbase64char('z') == 51); + assert_se(unbase64char('0') == 52); + assert_se(unbase64char('9') == 61); + assert_se(unbase64char('+') == 62); + assert_se(unbase64char('/') == 63); + assert_se(unbase64char('=') == -EINVAL); +} + static void test_octchar(void) { assert_se(octchar(00) == '0'); assert_se(octchar(07) == '7'); @@ -410,6 +443,264 @@ static void test_undecchar(void) { assert_se(undecchar('9') == 9); } +static void test_unhexmem(void) { + const char *hex = "efa214921"; + const char *hex_invalid = "efa214921o"; + _cleanup_free_ char *hex2 = NULL; + _cleanup_free_ void *mem = NULL; + size_t len; + + assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0); + assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL); + assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL); + + assert_se((hex2 = hexmem(mem, len))); + + free(mem); + + assert_se(memcmp(hex, hex2, strlen(hex)) == 0); + + free(hex2); + + assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == 0); + assert_se((hex2 = hexmem(mem, len))); + assert_se(memcmp(hex, hex2, strlen(hex) - 1) == 0); +} + +/* https://tools.ietf.org/html/rfc4648#section-10 */ +static void test_base32hexmem(void) { + char *b32; + + b32 = base32hexmem("", strlen(""), true); + assert_se(b32); + assert_se(streq(b32, "")); + free(b32); + + b32 = base32hexmem("f", strlen("f"), true); + assert_se(b32); + assert_se(streq(b32, "CO======")); + free(b32); + + b32 = base32hexmem("fo", strlen("fo"), true); + assert_se(b32); + assert_se(streq(b32, "CPNG====")); + free(b32); + + b32 = base32hexmem("foo", strlen("foo"), true); + assert_se(b32); + assert_se(streq(b32, "CPNMU===")); + free(b32); + + b32 = base32hexmem("foob", strlen("foob"), true); + assert_se(b32); + assert_se(streq(b32, "CPNMUOG=")); + free(b32); + + b32 = base32hexmem("fooba", strlen("fooba"), true); + assert_se(b32); + assert_se(streq(b32, "CPNMUOJ1")); + free(b32); + + b32 = base32hexmem("foobar", strlen("foobar"), true); + assert_se(b32); + assert_se(streq(b32, "CPNMUOJ1E8======")); + free(b32); + + b32 = base32hexmem("", strlen(""), false); + assert_se(b32); + assert_se(streq(b32, "")); + free(b32); + + b32 = base32hexmem("f", strlen("f"), false); + assert_se(b32); + assert_se(streq(b32, "CO")); + free(b32); + + b32 = base32hexmem("fo", strlen("fo"), false); + assert_se(b32); + assert_se(streq(b32, "CPNG")); + free(b32); + + b32 = base32hexmem("foo", strlen("foo"), false); + assert_se(b32); + assert_se(streq(b32, "CPNMU")); + free(b32); + + b32 = base32hexmem("foob", strlen("foob"), false); + assert_se(b32); + assert_se(streq(b32, "CPNMUOG")); + free(b32); + + b32 = base32hexmem("fooba", strlen("fooba"), false); + assert_se(b32); + assert_se(streq(b32, "CPNMUOJ1")); + free(b32); + + b32 = base32hexmem("foobar", strlen("foobar"), false); + assert_se(b32); + assert_se(streq(b32, "CPNMUOJ1E8")); + free(b32); +} + +static void test_unbase32hexmem(void) { + void *mem; + size_t len; + + assert_se(unbase32hexmem("", strlen(""), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "")); + free(mem); + + assert_se(unbase32hexmem("CO======", strlen("CO======"), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "f")); + free(mem); + + assert_se(unbase32hexmem("CPNG====", strlen("CPNG===="), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "fo")); + free(mem); + + assert_se(unbase32hexmem("CPNMU===", strlen("CPNMU==="), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foo")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foob")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "fooba")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), true, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foobar")); + free(mem); + + assert_se(unbase32hexmem("A", strlen("A"), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("A=======", strlen("A======="), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAA=====", strlen("AAA====="), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAAAA==", strlen("AAAAAA=="), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AB======", strlen("AB======"), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAB====", strlen("AAAB===="), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAAB===", strlen("AAAAB==="), true, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAAAAB=", strlen("AAAAAAB="), true, &mem, &len) == -EINVAL); + + assert_se(unbase32hexmem("", strlen(""), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "")); + free(mem); + + assert_se(unbase32hexmem("CO", strlen("CO"), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "f")); + free(mem); + + assert_se(unbase32hexmem("CPNG", strlen("CPNG"), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "fo")); + free(mem); + + assert_se(unbase32hexmem("CPNMU", strlen("CPNMU"), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foo")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOG", strlen("CPNMUOG"), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foob")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOJ1", strlen("CPNMUOJ1"), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "fooba")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOJ1E8", strlen("CPNMUOJ1E8"), false, &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foobar")); + free(mem); + + assert_se(unbase32hexmem("CPNMUOG=", strlen("CPNMUOG="), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("CPNMUOJ1E8======", strlen("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("A", strlen("A"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAA", strlen("AAA"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAAAA", strlen("AAAAAA"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AB", strlen("AB"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAB", strlen("AAAB"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAAB", strlen("AAAAB"), false, &mem, &len) == -EINVAL); + assert_se(unbase32hexmem("AAAAAAB", strlen("AAAAAAB"), false, &mem, &len) == -EINVAL); +} + +/* https://tools.ietf.org/html/rfc4648#section-10 */ +static void test_base64mem(void) { + char *b64; + + b64 = base64mem("", strlen("")); + assert_se(b64); + assert_se(streq(b64, "")); + free(b64); + + b64 = base64mem("f", strlen("f")); + assert_se(b64); + assert_se(streq(b64, "Zg==")); + free(b64); + + b64 = base64mem("fo", strlen("fo")); + assert_se(b64); + assert_se(streq(b64, "Zm8=")); + free(b64); + + b64 = base64mem("foo", strlen("foo")); + assert_se(b64); + assert_se(streq(b64, "Zm9v")); + free(b64); + + b64 = base64mem("foob", strlen("foob")); + assert_se(b64); + assert_se(streq(b64, "Zm9vYg==")); + free(b64); + + b64 = base64mem("fooba", strlen("fooba")); + assert_se(b64); + assert_se(streq(b64, "Zm9vYmE=")); + free(b64); + + b64 = base64mem("foobar", strlen("foobar")); + assert_se(b64); + assert_se(streq(b64, "Zm9vYmFy")); + free(b64); +} + +static void test_unbase64mem(void) { + void *mem; + size_t len; + + assert_se(unbase64mem("", strlen(""), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "")); + free(mem); + + assert_se(unbase64mem("Zg==", strlen("Zg=="), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "f")); + free(mem); + + assert_se(unbase64mem("Zm8=", strlen("Zm8="), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "fo")); + free(mem); + + assert_se(unbase64mem("Zm9v", strlen("Zm9v"), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foo")); + free(mem); + + assert_se(unbase64mem("Zm9vYg==", strlen("Zm9vYg=="), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foob")); + free(mem); + + assert_se(unbase64mem("Zm9vYmE=", strlen("Zm9vYmE="), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "fooba")); + free(mem); + + assert_se(unbase64mem("Zm9vYmFy", strlen("Zm9vYmFy"), &mem, &len) == 0); + assert_se(streq(strndupa(mem, len), "foobar")); + free(mem); + + assert_se(unbase64mem("A", strlen("A"), &mem, &len) == -EINVAL); + assert_se(unbase64mem("A====", strlen("A===="), &mem, &len) == -EINVAL); + assert_se(unbase64mem("AAB==", strlen("AAB=="), &mem, &len) == -EINVAL); + assert_se(unbase64mem("AAAB=", strlen("AAAB="), &mem, &len) == -EINVAL); +} + static void test_cescape(void) { _cleanup_free_ char *escaped; @@ -565,14 +856,14 @@ static void test_read_hostname_config(void) { close(fd); /* simple hostname */ - write_string_file(path, "foo"); + write_string_file(path, "foo", WRITE_STRING_FILE_CREATE); assert_se(read_hostname_config(path, &hostname) == 0); assert_se(streq(hostname, "foo")); free(hostname); hostname = NULL; /* with comment */ - write_string_file(path, "# comment\nfoo"); + write_string_file(path, "# comment\nfoo", WRITE_STRING_FILE_CREATE); assert_se(read_hostname_config(path, &hostname) == 0); assert_se(hostname); assert_se(streq(hostname, "foo")); @@ -580,7 +871,7 @@ static void test_read_hostname_config(void) { hostname = NULL; /* with comment and extra whitespace */ - write_string_file(path, "# comment\n\n foo "); + write_string_file(path, "# comment\n\n foo ", WRITE_STRING_FILE_CREATE); assert_se(read_hostname_config(path, &hostname) == 0); assert_se(hostname); assert_se(streq(hostname, "foo")); @@ -588,7 +879,7 @@ static void test_read_hostname_config(void) { hostname = NULL; /* cleans up name */ - write_string_file(path, "!foo/bar.com"); + write_string_file(path, "!foo/bar.com", WRITE_STRING_FILE_CREATE); assert_se(read_hostname_config(path, &hostname) == 0); assert_se(hostname); assert_se(streq(hostname, "foobar.com")); @@ -597,7 +888,7 @@ static void test_read_hostname_config(void) { /* no value set */ hostname = (char*) 0x1234; - write_string_file(path, "# nothing here\n"); + write_string_file(path, "# nothing here\n", WRITE_STRING_FILE_CREATE); assert_se(read_hostname_config(path, &hostname) == -ENOENT); assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */ @@ -1191,11 +1482,11 @@ static void test_execute_directory(void) { masked = strjoina(template_lo, "/masked"); mask = strjoina(template_hi, "/masked"); - assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works") == 0); - assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2") == 0); - assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0); - assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0") == 0); - assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed") == 0); + assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0); assert_se(symlink("/dev/null", mask) == 0); assert_se(chmod(name, 0755) == 0); assert_se(chmod(name2, 0755) == 0); @@ -1398,6 +1689,17 @@ static void test_unquote_first_word(void) { assert_se(streq(t, "\\w+\b")); free(t); assert_se(p == original + 5); + + p = original = "-N ''"; + assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0); + assert_se(streq(t, "-N")); + free(t); + assert_se(p == original + 3); + + assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0); + assert_se(streq(t, "")); + free(t); + assert_se(p == original + 5); } static void test_unquote_first_word_and_warn(void) { @@ -1804,10 +2106,19 @@ int main(int argc, char *argv[]) { test_in_charset(); test_hexchar(); test_unhexchar(); + test_base32hexchar(); + test_unbase32hexchar(); + test_base64char(); + test_unbase64char(); test_octchar(); test_unoctchar(); test_decchar(); test_undecchar(); + test_unhexmem(); + test_base32hexmem(); + test_unbase32hexmem(); + test_base64mem(); + test_unbase64mem(); test_cescape(); test_cunescape(); test_foreach_word(); |