1/* Test the sprintf (buf, "%s", buf) does not override buf.
2 Copyright (C) 2019-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <stdarg.h>
20#include <stdio.h>
21#include <string.h>
22
23#include <support/check.h>
24
25enum
26{
27 FUNCTION_FIRST,
28 FUNCTION_SPRINTF = FUNCTION_FIRST,
29 FUNCTION_SNPRINF,
30 FUNCTION_VSPRINTF,
31 FUNCTION_VSNPRINTF,
32 FUNCTION_LAST
33};
34
35static void
36do_one_test (int function, char *buf, ...)
37{
38 va_list args;
39 char *arg;
40
41 /* Expected results for fortified and non-fortified sprintf. */
42#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 1
43 const char *expected = "CD";
44#else
45 const char *expected = "ABCD";
46#endif
47
48 va_start (args, buf);
49 arg = va_arg (args, char *);
50 va_end (args);
51
52 switch (function)
53 {
54 /* The regular sprintf and vsprintf functions do not override the
55 destination buffer, even if source and destination overlap. */
56 case FUNCTION_SPRINTF:
57 sprintf (buf, "%sCD", buf);
58 TEST_COMPARE_STRING (buf, expected);
59 break;
60 case FUNCTION_VSPRINTF:
61 va_start (args, buf);
62 vsprintf (s: arg, fmt: "%sCD", ap: args);
63 TEST_COMPARE_STRING (arg, expected);
64 va_end (args);
65 break;
66 /* On the other hand, snprint and vsnprint override overlapping
67 source and destination buffers. */
68 case FUNCTION_SNPRINF:
69 snprintf (buf, 3, "%sCD", buf);
70 TEST_COMPARE_STRING (buf, "CD");
71 break;
72 case FUNCTION_VSNPRINTF:
73 va_start (args, buf);
74 vsnprintf (s: arg, n: 3, fmt: "%sCD", ap: args);
75 TEST_COMPARE_STRING (arg, "CD");
76 va_end (args);
77 break;
78 default:
79 support_record_failure ();
80 }
81}
82
83static int
84do_test (void)
85{
86 char buf[8];
87 int i;
88
89 /* For each function in the enum do:
90 - reset the buffer to the initial state "AB";
91 - call the function with buffer as source and destination;
92 - check for the desired behavior. */
93 for (i = FUNCTION_FIRST; i < FUNCTION_LAST; i++)
94 {
95 strncpy (buf, "AB", 3);
96 do_one_test (function: i, buf, buf);
97 }
98
99 return 0;
100}
101
102#include <support/test-driver.c>
103

source code of glibc/libio/tst-sprintf-ub.c