| 2297 | TEXTB[LENB] must be zero. */ |
| 2298 | |
| 2299 | static int |
| 2300 | compare_random (char *restrict texta, size_t lena, |
| 2301 | char *restrict textb, size_t lenb) |
| 2302 | { |
| 2303 | /* XFRM_DIFF records the equivalent of memcmp on the transformed |
| 2304 | data. This is used to break ties if there is a checksum |
| 2305 | collision, and this is good enough given the astronomically low |
| 2306 | probability of a collision. */ |
| 2307 | int xfrm_diff = 0; |
| 2308 | |
| 2309 | char stackbuf[4000]; |
| 2310 | char *buf = stackbuf; |
| 2311 | size_t bufsize = sizeof stackbuf; |
| 2312 | void *allocated = NULL; |
| 2313 | uint32_t dig[2][MD5_DIGEST_SIZE / sizeof (uint32_t)]; |
| 2314 | struct md5_ctx s[2]; |
| 2315 | s[0] = s[1] = random_md5_state; |
| 2316 | |
| 2317 | if (hard_LC_COLLATE) |
| 2318 | { |
| 2319 | char const *lima = texta + lena; |
| 2320 | char const *limb = textb + lenb; |
| 2321 | |
| 2322 | while (true) |
| 2323 | { |
| 2324 | /* Transform the text into the basis of comparison, so that byte |
| 2325 | strings that would otherwise considered to be equal are |
| 2326 | considered equal here even if their bytes differ. |
| 2327 | |
| 2328 | Each time through this loop, transform one |
| 2329 | null-terminated string's worth from TEXTA or from TEXTB |
| 2330 | or both. That way, there's no need to store the |
| 2331 | transformation of the whole line, if it contains many |
| 2332 | null-terminated strings. */ |
| 2333 | |
| 2334 | /* Store the transformed data into a big-enough buffer. */ |
| 2335 | |
| 2336 | /* A 3X size guess avoids the overhead of calling strxfrm |
| 2337 | twice on typical implementations. Don't worry about |
| 2338 | size_t overflow, as the guess need not be correct. */ |
| 2339 | size_t guess_bufsize = 3 * (lena + lenb) + 2; |
| 2340 | if (bufsize < guess_bufsize) |
| 2341 | { |
| 2342 | bufsize = MAX (guess_bufsize, bufsize * 3 / 2); |
| 2343 | free (allocated); |
| 2344 | buf = allocated = malloc (bufsize); |
| 2345 | if (! buf) |
| 2346 | { |
| 2347 | buf = stackbuf; |
| 2348 | bufsize = sizeof stackbuf; |
| 2349 | } |
| 2350 | } |
| 2351 | |
| 2352 | size_t sizea = |
| 2353 | (texta < lima ? xstrxfrm (buf, texta, bufsize) + 1 : 0); |
| 2354 | bool a_fits = sizea <= bufsize; |
| 2355 | size_t sizeb = |
| 2356 | (textb < limb |
no test coverage detected