diff options
author | Dan McDonald <danmcd@mnx.io> | 2022-09-06 22:57:04 -0400 |
---|---|---|
committer | Dan McDonald <danmcd@mnx.io> | 2022-09-06 22:57:04 -0400 |
commit | 054936a1c946defd71850a10311181d0f91492c7 (patch) | |
tree | cdf21170eab4821fcfa7c90a2bd6aa7214161017 /usr/src/test/libc-tests/tests/asprintf-14933.c | |
parent | 27b037a7c4032bcea69b12d1252225a3ea7c755f (diff) | |
parent | 4322dd9069f078f823a09309fbdfc08ed9085b8d (diff) | |
download | illumos-joyent-release-20220908.tar.gz |
[illumos-gate merge]release-20220908
commit 4322dd9069f078f823a09309fbdfc08ed9085b8d
14933 asprintf(3c) is confused by NUL
Diffstat (limited to 'usr/src/test/libc-tests/tests/asprintf-14933.c')
-rw-r--r-- | usr/src/test/libc-tests/tests/asprintf-14933.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/usr/src/test/libc-tests/tests/asprintf-14933.c b/usr/src/test/libc-tests/tests/asprintf-14933.c new file mode 100644 index 0000000000..e63c0436d1 --- /dev/null +++ b/usr/src/test/libc-tests/tests/asprintf-14933.c @@ -0,0 +1,97 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2022 Oxide Computer Company + */ + +/* + * This is a regression test for illumos#14933 where asprintf() in small buffers + * was thrown off by an embedded NUL. Test both short and large buffers with + * embedded NULs. "large" at the time 14933 was anything that exceeded 128 + * bytes. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <sys/sysmacros.h> + +const char *longstr = "0123456789abcdefghijklmnopqrstuvwxyz"; + +int +main(void) +{ + int eval = EXIT_SUCCESS; + char short_exp[] = { '0', '1', '2', '3', '\0', 'a', 'b', 'c', '\0' }; + size_t short_len = ARRAY_SIZE(short_exp); + size_t long_len; + char *out; + int ret; + + ret = asprintf(&out, "%s%c%s", "0123", '\0', "abc"); + if (ret != short_len - 1) { + (void) fprintf(stderr, "TEST FAILED: short asprintf returned " + "wrong length: found %u, expected %u\n", ret, + short_len - 1); + eval = EXIT_FAILURE; + } else { + (void) printf("TEST PASSED: short buffer embedded nul has " + "correct length\n"); + } + + if (memcmp(short_exp, out, short_len) != 0) { + (void) fprintf(stderr, "TEST FAILED: short example returned " + "wrong value\nexpected:"); + for (size_t i = 0; i < short_len; i++) { + (void) fprintf(stderr, " 0x%02x", short_exp[i]); + } + (void) fprintf(stderr, "\nactual: "); + for (size_t i = 0; i < short_len; i++) { + (void) fprintf(stderr, " 0x%02x", out[i]); + } + (void) fputc('\n', stderr); + eval = EXIT_FAILURE; + } else { + (void) printf("TEST PASSED: short buffer data contents " + "match\n"); + } + + free(out); + long_len = strlen(longstr) * 5 + 5; + ret = asprintf(&out, "%s%c%s%c%s%c%s%c%s", longstr, '\0', longstr, '\0', + longstr, '\0', longstr, '\0', longstr); + if (ret != long_len - 1) { + (void) fprintf(stderr, "TEST FAILED: long asprintf returned " + "wrong length: found %u, expected %u\n", ret, long_len - 1); + eval = EXIT_FAILURE; + } else { + (void) printf("TEST PASSED: long buffer embedded nul has " + "correct length\n"); + } + + bool large_pass = true; + for (uint_t i = 0; i < 5; i++) { + size_t offset = (strlen(longstr) + 1) * i; + if (strcmp(longstr, out + offset) != 0) { + (void) fprintf(stderr, "TEST FAILED: long asprintf " + "data buffer mismatch at copy %u\n", i); + eval = EXIT_FAILURE; + large_pass = false; + } + } + if (large_pass) { + (void) printf("TEST PASSED: long buffer data contents match\n"); + } + + return (eval); +} |