1 /* Alignment/padding coverage test for string comparison.
2 Copyright (C) 2016-2020 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 return strncmp (left
, right
, SIZE_MAX
);
109 DIAG_POP_NEEDS_COMMENT
;
113 strncasecmp_max (const char *left
, const char *right
)
115 DIAG_PUSH_NEEDS_COMMENT
;
116 #if __GNUC_PREREQ (7, 0)
117 /* GCC 9 warns about the size passed to strncasecmp being larger
118 than PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
119 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
121 return strncasecmp (left
, right
, SIZE_MAX
);
122 DIAG_POP_NEEDS_COMMENT
;
130 max_string_length
= 33
132 size_t blob_size
= max_align
+ max_string_length
+ 1;
133 char *left
= memalign (max_align
, blob_size
);
134 char *right
= memalign (max_align
, blob_size
);
135 if (left
== NULL
|| right
== NULL
)
137 printf ("error: out of memory\n");
144 int (*implementation
) (const char *, const char *);
147 { "strcmp", strcmp
},
148 { "strcasecmp", strcasecmp
},
149 { "strncmp (without NUL)", strncmp_no_terminator
},
150 { "strncasecmp (without NUL)", strncasecmp_no_terminator
},
151 { "strncmp (with NUL)", strncmp_terminator
},
152 { "strncasecmp (with NUL)", strncasecmp_terminator
},
153 { "strncmp (length 64)", strncmp_64
},
154 { "strncasecmp (length 64)", strncasecmp_64
},
155 { "strncmp (length SIZE_MAX)", strncmp_max
},
156 { "strncasecmp (length SIZE_MAX)", strncasecmp_max
},
159 const char *const strings
[] =
174 "abcdefghijklmnopqrstuvwxyzABCDEF",
177 const unsigned char pads
[] =
178 { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
181 for (int left_idx
= 0; strings
[left_idx
] != NULL
; ++left_idx
)
182 for (int left_align
= 0; left_align
< max_align
; ++left_align
)
183 for (unsigned pad_left
= 0; pad_left
< sizeof (pads
); ++pad_left
)
185 memset (left
, pads
[pad_left
], blob_size
);
186 strcpy (left
+ left_align
, strings
[left_idx
]);
188 for (int right_idx
= 0; strings
[right_idx
] != NULL
; ++right_idx
)
189 for (unsigned pad_right
= 0; pad_right
< sizeof (pads
);
191 for (int right_align
= 0; right_align
< max_align
;
194 memset (right
, pads
[pad_right
], blob_size
);
195 strcpy (right
+ right_align
, strings
[right_idx
]);
197 for (int func
= 0; functions
[func
].name
!= NULL
; ++func
)
199 int expected
= left_idx
- right_idx
;
200 int actual
= functions
[func
].implementation
201 (left
+ left_align
, right
+ right_align
);
202 if (signum (actual
) != signum (expected
))
204 printf ("error: mismatch for %s: %d\n"
207 " pad_left = %u, pad_right = %u,\n"
208 " left_align = %d, right_align = %d\n",
209 functions
[func
].name
, actual
,
210 strings
[left_idx
], strings
[right_idx
],
212 left_align
, right_align
);
223 /* The nested loops need a long time to complete on slower
227 #include <support/test-driver.c>