1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2022 Oxide Computer Company 14 */ 15 16 /* 17 * This is a regression test for illumos#14933 where asprintf() in small buffers 18 * was thrown off by an embedded NUL. Test both short and large buffers with 19 * embedded NULs. "large" at the time 14933 was anything that exceeded 128 20 * bytes. 21 */ 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <stdbool.h> 27 #include <sys/sysmacros.h> 28 29 const char *longstr = "0123456789abcdefghijklmnopqrstuvwxyz"; 30 31 int 32 main(void) 33 { 34 int eval = EXIT_SUCCESS; 35 char short_exp[] = { '0', '1', '2', '3', '\0', 'a', 'b', 'c', '\0' }; 36 size_t short_len = ARRAY_SIZE(short_exp); 37 size_t long_len; 38 char *out; 39 int ret; 40 41 ret = asprintf(&out, "%s%c%s", "0123", '\0', "abc"); 42 if (ret != short_len - 1) { 43 (void) fprintf(stderr, "TEST FAILED: short asprintf returned " 44 "wrong length: found %u, expected %u\n", ret, 45 short_len - 1); 46 eval = EXIT_FAILURE; 47 } else { 48 (void) printf("TEST PASSED: short buffer embedded nul has " 49 "correct length\n"); 50 } 51 52 if (memcmp(short_exp, out, short_len) != 0) { 53 (void) fprintf(stderr, "TEST FAILED: short example returned " 54 "wrong value\nexpected:"); 55 for (size_t i = 0; i < short_len; i++) { 56 (void) fprintf(stderr, " 0x%02x", short_exp[i]); 57 } 58 (void) fprintf(stderr, "\nactual: "); 59 for (size_t i = 0; i < short_len; i++) { 60 (void) fprintf(stderr, " 0x%02x", out[i]); 61 } 62 (void) fputc('\n', stderr); 63 eval = EXIT_FAILURE; 64 } else { 65 (void) printf("TEST PASSED: short buffer data contents " 66 "match\n"); 67 } 68 69 free(out); 70 long_len = strlen(longstr) * 5 + 5; 71 ret = asprintf(&out, "%s%c%s%c%s%c%s%c%s", longstr, '\0', longstr, '\0', 72 longstr, '\0', longstr, '\0', longstr); 73 if (ret != long_len - 1) { 74 (void) fprintf(stderr, "TEST FAILED: long asprintf returned " 75 "wrong length: found %u, expected %u\n", ret, long_len - 1); 76 eval = EXIT_FAILURE; 77 } else { 78 (void) printf("TEST PASSED: long buffer embedded nul has " 79 "correct length\n"); 80 } 81 82 bool large_pass = true; 83 for (uint_t i = 0; i < 5; i++) { 84 size_t offset = (strlen(longstr) + 1) * i; 85 if (strcmp(longstr, out + offset) != 0) { 86 (void) fprintf(stderr, "TEST FAILED: long asprintf " 87 "data buffer mismatch at copy %u\n", i); 88 eval = EXIT_FAILURE; 89 large_pass = false; 90 } 91 } 92 if (large_pass) { 93 (void) printf("TEST PASSED: long buffer data contents match\n"); 94 } 95 96 return (eval); 97 } 98