1 /* Alignment/padding coverage test for string comparison.
2 Copyright (C) 2016-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 /* This performs test comparisons with various (mis)alignments and
20 characters in the padding. It is partly a regression test for bug
29 #include <libc-diag.h>
43 max_size_t (size_t left
, size_t right
)
51 /* Wrappers for strncmp and strncasecmp which determine the maximum
52 string length in some, either based on the input string length, or
53 using fixed constants. */
56 strncmp_no_terminator (const char *left
, const char *right
)
58 size_t left_len
= strlen (left
);
59 size_t right_len
= strlen (right
);
60 return strncmp (left
, right
, max_size_t (left_len
, right_len
));
64 strncasecmp_no_terminator (const char *left
, const char *right
)
66 size_t left_len
= strlen (left
);
67 size_t right_len
= strlen (right
);
68 return strncasecmp (left
, right
, max_size_t (left_len
, right_len
));
72 strncmp_terminator (const char *left
, const char *right
)
74 size_t left_len
= strlen (left
);
75 size_t right_len
= strlen (right
);
76 return strncmp (left
, right
, max_size_t (left_len
, right_len
));
80 strncasecmp_terminator (const char *left
, const char *right
)
82 size_t left_len
= strlen (left
);
83 size_t right_len
= strlen (right
);
84 return strncasecmp (left
, right
, max_size_t (left_len
, right_len
));
88 strncmp_64 (const char *left
, const char *right
)
90 return strncmp (left
, right
, 64);
94 strncasecmp_64 (const char *left
, const char *right
)
96 return strncasecmp (left
, right
, 64);
100 strncmp_max (const char *left
, const char *right
)
102 DIAG_PUSH_NEEDS_COMMENT
;
103 #if __GNUC_PREREQ (7, 0)
104 /* GCC 9 warns about the size passed to strncmp being larger than
105 PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
106 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
108 #if __GNUC_PREREQ (11, 0)
109 /* Likewise GCC 11, with a different warning option. */
110 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
112 return strncmp (left
, right
, SIZE_MAX
);
113 DIAG_POP_NEEDS_COMMENT
;
117 strncasecmp_max (const char *left
, const char *right
)
119 DIAG_PUSH_NEEDS_COMMENT
;
120 #if __GNUC_PREREQ (7, 0)
121 /* GCC 9 warns about the size passed to strncasecmp being larger
122 than PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
123 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
125 #if __GNUC_PREREQ (11, 0)
126 /* Likewise GCC 11, with a different warning option. */
127 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
129 return strncasecmp (left
, right
, SIZE_MAX
);
130 DIAG_POP_NEEDS_COMMENT
;
138 max_string_length
= 33
140 size_t blob_size
= max_align
+ max_string_length
+ 1;
141 char *left
= memalign (max_align
, blob_size
);
142 char *right
= memalign (max_align
, blob_size
);
143 if (left
== NULL
|| right
== NULL
)
145 printf ("error: out of memory\n");
152 int (*implementation
) (const char *, const char *);
155 { "strcmp", strcmp
},
156 { "strcasecmp", strcasecmp
},
157 { "strncmp (without NUL)", strncmp_no_terminator
},
158 { "strncasecmp (without NUL)", strncasecmp_no_terminator
},
159 { "strncmp (with NUL)", strncmp_terminator
},
160 { "strncasecmp (with NUL)", strncasecmp_terminator
},
161 { "strncmp (length 64)", strncmp_64
},
162 { "strncasecmp (length 64)", strncasecmp_64
},
163 { "strncmp (length SIZE_MAX)", strncmp_max
},
164 { "strncasecmp (length SIZE_MAX)", strncasecmp_max
},
167 const char *const strings
[] =
182 "abcdefghijklmnopqrstuvwxyzABCDEF",
185 const unsigned char pads
[] =
186 { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
189 for (int left_idx
= 0; strings
[left_idx
] != NULL
; ++left_idx
)
190 for (int left_align
= 0; left_align
< max_align
; ++left_align
)
191 for (unsigned pad_left
= 0; pad_left
< sizeof (pads
); ++pad_left
)
193 memset (left
, pads
[pad_left
], blob_size
);
194 strcpy (left
+ left_align
, strings
[left_idx
]);
196 for (int right_idx
= 0; strings
[right_idx
] != NULL
; ++right_idx
)
197 for (unsigned pad_right
= 0; pad_right
< sizeof (pads
);
199 for (int right_align
= 0; right_align
< max_align
;
202 memset (right
, pads
[pad_right
], blob_size
);
203 strcpy (right
+ right_align
, strings
[right_idx
]);
205 for (int func
= 0; functions
[func
].name
!= NULL
; ++func
)
207 int expected
= left_idx
- right_idx
;
208 int actual
= functions
[func
].implementation
209 (left
+ left_align
, right
+ right_align
);
210 if (signum (actual
) != signum (expected
))
212 printf ("error: mismatch for %s: %d\n"
215 " pad_left = %u, pad_right = %u,\n"
216 " left_align = %d, right_align = %d\n",
217 functions
[func
].name
, actual
,
218 strings
[left_idx
], strings
[right_idx
],
220 left_align
, right_align
);
231 /* The nested loops need a long time to complete on slower
235 #include <support/test-driver.c>