Message ID | 20211104130031.185958-1-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | [v2] locale: Fix localedata/sort-test undefined behavior | expand |
On Thu, Nov 4, 2021 at 6:01 AM Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org> wrote: > > The collate-test.c triggers UB with an signed integer overflow, > which results in an error on some architectures (powerpc32). > > Checked on x86_64, i686, and powerpc. > --- > localedata/collate-test.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/localedata/collate-test.c b/localedata/collate-test.c > index 46b91ec57f..e6ca7e8e8b 100644 > --- a/localedata/collate-test.c > +++ b/localedata/collate-test.c > @@ -32,6 +32,11 @@ struct lines > > static int xstrcoll (const void *, const void *); > > +static int signum (int n) signum on a separate line? > +{ > + return (0 < n) - (n < 0); > +} > + > int > main (int argc, char *argv[]) > { > @@ -86,7 +91,7 @@ main (int argc, char *argv[]) > srandom (atoi (argv[1])); > for (n = 0; n < 10 * nstrings; ++n) > { > - int r1, r2, r; > + int r1, r2; > size_t idx1 = random () % nstrings; > size_t idx2 = random () % nstrings; > struct lines tmp = strings[idx1]; > @@ -96,9 +101,8 @@ main (int argc, char *argv[]) > /* While we are at it a first little test. */ > r1 = strcoll (strings[idx1].key, strings[idx2].key); > r2 = strcoll (strings[idx2].key, strings[idx1].key); > - r = r1 * r2; > > - if (r > 0 || (r == 0 && r1 != 0) || (r == 0 && r2 != 0)) > + if (signum (r1) != - signum (r2)) > printf ("`%s' and `%s' collate wrong: %d vs. %d\n", > strings[idx1].key, strings[idx2].key, r1, r2); > } > -- > 2.32.0 >
diff --git a/localedata/collate-test.c b/localedata/collate-test.c index 46b91ec57f..e6ca7e8e8b 100644 --- a/localedata/collate-test.c +++ b/localedata/collate-test.c @@ -32,6 +32,11 @@ struct lines static int xstrcoll (const void *, const void *); +static int signum (int n) +{ + return (0 < n) - (n < 0); +} + int main (int argc, char *argv[]) { @@ -86,7 +91,7 @@ main (int argc, char *argv[]) srandom (atoi (argv[1])); for (n = 0; n < 10 * nstrings; ++n) { - int r1, r2, r; + int r1, r2; size_t idx1 = random () % nstrings; size_t idx2 = random () % nstrings; struct lines tmp = strings[idx1]; @@ -96,9 +101,8 @@ main (int argc, char *argv[]) /* While we are at it a first little test. */ r1 = strcoll (strings[idx1].key, strings[idx2].key); r2 = strcoll (strings[idx2].key, strings[idx1].key); - r = r1 * r2; - if (r > 0 || (r == 0 && r1 != 0) || (r == 0 && r2 != 0)) + if (signum (r1) != - signum (r2)) printf ("`%s' and `%s' collate wrong: %d vs. %d\n", strings[idx1].key, strings[idx2].key, r1, r2); }