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 
25 enum
26 {
27   FUNCTION_FIRST,
28   FUNCTION_SPRINTF = FUNCTION_FIRST,
29   FUNCTION_SNPRINF,
30   FUNCTION_VSPRINTF,
31   FUNCTION_VSNPRINTF,
32   FUNCTION_LAST
33 };
34 
35 static void
do_one_test(int function,char * buf,...)36 do_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 (arg, "%sCD", 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 (arg, 3, "%sCD", args);
75         TEST_COMPARE_STRING (arg, "CD");
76         va_end (args);
77         break;
78       default:
79         support_record_failure ();
80     }
81 }
82 
83 static int
do_test(void)84 do_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 (i, buf, buf);
97     }
98 
99   return 0;
100 }
101 
102 #include <support/test-driver.c>
103