Warning: That file was not part of the compilation database. It may have many parsing errors.

1 | /* Test and measure strncasecmp functions. |
---|---|

2 | Copyright (C) 1999-2019 Free Software Foundation, Inc. |

3 | This file is part of the GNU C Library. |

4 | Written by Jakub Jelinek <jakub@redhat.com>, 1999. |

5 | |

6 | The GNU C Library is free software; you can redistribute it and/or |

7 | modify it under the terms of the GNU Lesser General Public |

8 | License as published by the Free Software Foundation; either |

9 | version 2.1 of the License, or (at your option) any later version. |

10 | |

11 | The GNU C Library is distributed in the hope that it will be useful, |

12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |

13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |

14 | Lesser General Public License for more details. |

15 | |

16 | You should have received a copy of the GNU Lesser General Public |

17 | License along with the GNU C Library; if not, see |

18 | <http://www.gnu.org/licenses/>. */ |

19 | |

20 | #include <locale.h> |

21 | #include <ctype.h> |

22 | #define TEST_MAIN |

23 | #define TEST_NAME "strncasecmp" |

24 | #include "test-string.h" |

25 | |

26 | typedef int (*proto_t) (const char *, const char *, size_t); |

27 | static int simple_strncasecmp (const char *, const char *, size_t); |

28 | static int stupid_strncasecmp (const char *, const char *, size_t); |

29 | |

30 | IMPL (stupid_strncasecmp, 0) |

31 | IMPL (simple_strncasecmp, 0) |

32 | IMPL (strncasecmp, 1) |

33 | |

34 | static int |

35 | simple_strncasecmp (const char *s1, const char *s2, size_t n) |

36 | { |

37 | int ret; |

38 | |

39 | if (n == 0) |

40 | return 0; |

41 | |

42 | while ((ret = ((unsigned char) tolower (*s1) |

43 | - (unsigned char) tolower (*s2))) == 0 |

44 | && *s1++) |

45 | { |

46 | if (--n == 0) |

47 | return 0; |

48 | ++s2; |

49 | } |

50 | return ret; |

51 | } |

52 | |

53 | static int |

54 | stupid_strncasecmp (const char *s1, const char *s2, size_t max) |

55 | { |

56 | size_t ns1 = strlen (s1) + 1; |

57 | size_t ns2 = strlen (s2) + 1; |

58 | size_t n = ns1 < ns2 ? ns1 : ns2; |

59 | if (n > max) |

60 | n = max; |

61 | int ret = 0; |

62 | |

63 | while (n--) |

64 | { |

65 | if ((ret = ((unsigned char) tolower (*s1) |

66 | - (unsigned char) tolower (*s2))) != 0) |

67 | break; |

68 | ++s1; |

69 | ++s2; |

70 | } |

71 | return ret; |

72 | } |

73 | |

74 | static int |

75 | check_result (impl_t *impl, const char *s1, const char *s2, size_t n, |

76 | int exp_result) |

77 | { |

78 | int result = CALL (impl, s1, s2, n); |

79 | if ((exp_result == 0 && result != 0) |

80 | || (exp_result < 0 && result >= 0) |

81 | || (exp_result > 0 && result <= 0)) |

82 | { |

83 | error (0, 0, "Wrong result in function %s %d %d", impl->name, |

84 | result, exp_result); |

85 | ret = 1; |

86 | return -1; |

87 | } |

88 | |

89 | return 0; |

90 | } |

91 | |

92 | static void |

93 | do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, |

94 | int exp_result) |

95 | { |

96 | if (check_result (impl, s1, s2, n, exp_result) < 0) |

97 | return; |

98 | } |

99 | |

100 | static void |

101 | do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, |

102 | int exp_result) |

103 | { |

104 | size_t i; |

105 | char *s1, *s2; |

106 | |

107 | if (len == 0) |

108 | return; |

109 | |

110 | align1 &= 7; |

111 | if (align1 + len + 1 >= page_size) |

112 | return; |

113 | |

114 | align2 &= 7; |

115 | if (align2 + len + 1 >= page_size) |

116 | return; |

117 | |

118 | s1 = (char *) (buf1 + align1); |

119 | s2 = (char *) (buf2 + align2); |

120 | |

121 | for (i = 0; i < len; i++) |

122 | { |

123 | s1[i] = toupper (1 + 23 * i % max_char); |

124 | s2[i] = tolower (s1[i]); |

125 | } |

126 | |

127 | s1[len] = s2[len] = 0; |

128 | s1[len + 1] = 23; |

129 | s2[len + 1] = 24 + exp_result; |

130 | if ((s2[len - 1] == 'z' && exp_result == -1) |

131 | || (s2[len - 1] == 'a' && exp_result == 1)) |

132 | s1[len - 1] += exp_result; |

133 | else |

134 | s2[len - 1] -= exp_result; |

135 | |

136 | FOR_EACH_IMPL (impl, 0) |

137 | do_one_test (impl, s1, s2, n, exp_result); |

138 | } |

139 | |

140 | static void |

141 | do_random_tests (void) |

142 | { |

143 | size_t i, j, n, align1, align2, pos, len1, len2; |

144 | int result; |

145 | long r; |

146 | unsigned char *p1 = buf1 + page_size - 512; |

147 | unsigned char *p2 = buf2 + page_size - 512; |

148 | |

149 | for (n = 0; n < ITERATIONS; n++) |

150 | { |

151 | align1 = random () & 31; |

152 | if (random () & 1) |

153 | align2 = random () & 31; |

154 | else |

155 | align2 = align1 + (random () & 24); |

156 | pos = random () & 511; |

157 | j = align1 > align2 ? align1 : align2; |

158 | if (pos + j >= 511) |

159 | pos = 510 - j - (random () & 7); |

160 | len1 = random () & 511; |

161 | if (pos >= len1 && (random () & 1)) |

162 | len1 = pos + (random () & 7); |

163 | if (len1 + j >= 512) |

164 | len1 = 511 - j - (random () & 7); |

165 | if (pos >= len1) |

166 | len2 = len1; |

167 | else |

168 | len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0); |

169 | j = (pos > len2 ? pos : len2) + align1 + 64; |

170 | if (j > 512) |

171 | j = 512; |

172 | for (i = 0; i < j; ++i) |

173 | { |

174 | p1[i] = tolower (random () & 255); |

175 | if (i < len1 + align1 && !p1[i]) |

176 | { |

177 | p1[i] = tolower (random () & 255); |

178 | if (!p1[i]) |

179 | p1[i] = tolower (1 + (random () & 127)); |

180 | } |

181 | } |

182 | for (i = 0; i < j; ++i) |

183 | { |

184 | p2[i] = toupper (random () & 255); |

185 | if (i < len2 + align2 && !p2[i]) |

186 | { |

187 | p2[i] = toupper (random () & 255); |

188 | if (!p2[i]) |

189 | toupper (p2[i] = 1 + (random () & 127)); |

190 | } |

191 | } |

192 | |

193 | result = 0; |

194 | memcpy (p2 + align2, p1 + align1, pos); |

195 | if (pos < len1) |

196 | { |

197 | if (tolower (p2[align2 + pos]) == p1[align1 + pos]) |

198 | { |

199 | p2[align2 + pos] = toupper (random () & 255); |

200 | if (tolower (p2[align2 + pos]) == p1[align1 + pos]) |

201 | p2[align2 + pos] = toupper (p1[align1 + pos] |

202 | + 3 + (random () & 127)); |

203 | } |

204 | |

205 | if (p1[align1 + pos] < tolower (p2[align2 + pos])) |

206 | result = -1; |

207 | else |

208 | result = 1; |

209 | } |

210 | p1[len1 + align1] = 0; |

211 | p2[len2 + align2] = 0; |

212 | |

213 | FOR_EACH_IMPL (impl, 1) |

214 | { |

215 | r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2), |

216 | pos + 1 + (random () & 255)); |

217 | /* Test whether on 64-bit architectures where ABI requires |

218 | callee to promote has the promotion been done. */ |

219 | asm ("": "=g"(r) : "0"(r)); |

220 | if ((r == 0 && result) |

221 | || (r < 0 && result >= 0) |

222 | || (r > 0 && result <= 0)) |

223 | { |

224 | error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p", |

225 | n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2); |

226 | ret = 1; |

227 | } |

228 | } |

229 | } |

230 | } |

231 | |

232 | /* Regression test for BZ #12205 */ |

233 | static void |

234 | bz12205 (void) |

235 | { |

236 | static char cp [4096+16] __attribute__ ((aligned(4096))); |

237 | static char gotrel[4096] __attribute__ ((aligned(4096))); |

238 | char *s1 = cp + 0xffa; |

239 | char *s2 = gotrel + 0xcbe; |

240 | int exp_result; |

241 | size_t n = 6; |

242 | |

243 | strcpy (s1, "gottpoff"); |

244 | strcpy (s2, "GOTPLT"); |

245 | |

246 | exp_result = simple_strncasecmp (s1, s2, n); |

247 | FOR_EACH_IMPL (impl, 0) |

248 | check_result (impl, s1, s2, n, exp_result); |

249 | } |

250 | |

251 | /* Regression test for BZ #14195 */ |

252 | static void |

253 | bz14195 (void) |

254 | { |

255 | const char *empty_string = ""; |

256 | FOR_EACH_IMPL (impl, 0) |

257 | check_result (impl, empty_string, "", 5, 0); |

258 | } |

259 | |

260 | static void |

261 | test_locale (const char *locale) |

262 | { |

263 | size_t i; |

264 | |

265 | if (setlocale (LC_CTYPE, locale) == NULL) |

266 | { |

267 | error (0, 0, "cannot set locale \"%s\"", locale); |

268 | ret = 1; |

269 | } |

270 | |

271 | bz12205 (); |

272 | bz14195 (); |

273 | |

274 | printf ("%23s", locale); |

275 | FOR_EACH_IMPL (impl, 0) |

276 | printf ("\t%s", impl->name); |

277 | putchar ('\n'); |

278 | |

279 | for (i = 1; i < 16; ++i) |

280 | { |

281 | do_test (i, i, i - 1, i, 127, 0); |

282 | |

283 | do_test (i, i, i, i, 127, 0); |

284 | do_test (i, i, i, i, 127, 1); |

285 | do_test (i, i, i, i, 127, -1); |

286 | |

287 | do_test (i, i, i + 1, i, 127, 0); |

288 | do_test (i, i, i + 1, i, 127, 1); |

289 | do_test (i, i, i + 1, i, 127, -1); |

290 | } |

291 | |

292 | for (i = 1; i < 10; ++i) |

293 | { |

294 | do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0); |

295 | do_test (0, 0, 2 << i, 2 << i, 254, 0); |

296 | do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0); |

297 | |

298 | do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0); |

299 | |

300 | do_test (0, 0, 2 << i, 2 << i, 127, 1); |

301 | do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1); |

302 | |

303 | do_test (0, 0, 2 << i, 2 << i, 254, 1); |

304 | do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1); |

305 | |

306 | do_test (0, 0, 2 << i, 2 << i, 127, -1); |

307 | do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1); |

308 | |

309 | do_test (0, 0, 2 << i, 2 << i, 254, -1); |

310 | do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1); |

311 | } |

312 | |

313 | for (i = 1; i < 8; ++i) |

314 | { |

315 | do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0); |

316 | do_test (i, 2 * i, 8 << i, 8 << i, 127, 0); |

317 | do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0); |

318 | |

319 | do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0); |

320 | do_test (2 * i, i, 8 << i, 8 << i, 254, 0); |

321 | do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0); |

322 | |

323 | do_test (i, 2 * i, 8 << i, 8 << i, 127, 1); |

324 | do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1); |

325 | |

326 | do_test (2 * i, i, 8 << i, 8 << i, 254, 1); |

327 | do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1); |

328 | |

329 | do_test (i, 2 * i, 8 << i, 8 << i, 127, -1); |

330 | do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1); |

331 | |

332 | do_test (2 * i, i, 8 << i, 8 << i, 254, -1); |

333 | do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1); |

334 | } |

335 | |

336 | do_random_tests (); |

337 | } |

338 | |

339 | int |

340 | test_main (void) |

341 | { |

342 | test_init (); |

343 | |

344 | test_locale ("C"); |

345 | test_locale ("en_US.ISO-8859-1"); |

346 | test_locale ("en_US.UTF-8"); |

347 | test_locale ("tr_TR.ISO-8859-9"); |

348 | test_locale ("tr_TR.UTF-8"); |

349 | |

350 | return ret; |

351 | } |

352 | |

353 | #include <support/test-driver.c> |

354 |

Warning: That file was not part of the compilation database. It may have many parsing errors.