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 2024 Bill Sommerfeld <sommerfeld@hamachi.org>
14 */
15
16 /*
17 * Regression test for illumos bug #16352: verify that strftime behaves
18 * properly if the buffer length is overly large.
19 */
20
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26
27 static int status = EXIT_SUCCESS;
28
29 static const char expected_buf[] = "2024 04 23";
30 static int expected_ret = 10;
31
32 static void
check_results(const char * name,int ret,const char * buf)33 check_results(const char *name, int ret, const char *buf)
34 {
35 if (ret == 0) {
36 fprintf(stderr, "TEST FAILED: %s returned 0\n", name);
37 status = EXIT_FAILURE;
38 }
39
40 if (ret != 10) {
41 fprintf(stderr, "TEST FAILED: %s length %d (expected %d)\n",
42 name, ret, expected_ret);
43 status = EXIT_FAILURE;
44 }
45
46 if (strcmp(buf, expected_buf) != 0) {
47 fprintf(stderr, "TEST FAILED: %s contents [%s]"
48 " (expected [%s])\n", name, buf, expected_buf);
49 status = EXIT_FAILURE;
50 }
51 }
52
53 int
main(void)54 main(void)
55 {
56 int ret;
57 struct tm t;
58 char buf[1024];
59
60 memset(&t, 0, sizeof (t));
61 t.tm_year = 124;
62 t.tm_mon = 3;
63 t.tm_mday = 23;
64
65 /*
66 * Test that ascftime() behaves properly; ascftime calls
67 * strftime(buf, LONG_MAX, format, t). For an unfixed libc,
68 * this will fail if buf lies above the midpoint of the
69 * process address space, as the computation of buf + len
70 * overflows and wraps around.
71 */
72 ret = ascftime(buf, "%Y %m %d", &t);
73 check_results("ascftime", ret, buf);
74
75 /*
76 * Repeat test with strftime passed the maximum possible length.
77 * This will wrap around as long as buf is not NULL, letting us
78 * exercise the fix even if the user address space is restricted
79 * in some way.
80 */
81 ret = strftime(buf, ULONG_MAX, "%Y %m %d", &t);
82 check_results("strftime", ret, buf);
83
84 if (status == EXIT_SUCCESS) {
85 (void) printf("TEST PASSED: observed expected output\n");
86 }
87 printf("NOTE: buffer is %p\n", buf);
88 return (status);
89 }
90