diff --git a/ChangeLog b/ChangeLog index 59fd5ae63..6eb6bba66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2012-05-04 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_strcmp): Use unsigned comparison as + per common usage and preffered in several parts of code. + (grub_memcmp): Likewise. + (grub_strncmp): Likewise. + * include/grub/misc.h (grub_strcasecmp): Likewise. + (grub_strncasecmp): Likewise. + * Makefile.util.def (cmp_test): New test. + (grub_script_strcmp): Likewise. + * tests/cmp_unit_test.c: New file. + * tests/grub_script_strcmp.in: Likewise. + * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey): Add a comment. + 2012-05-04 Vladimir Serbinenko * include/grub/pci.h: Move enums into no-asm part. diff --git a/Makefile.util.def b/Makefile.util.def index cf817c455..921305e9e 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -682,6 +682,12 @@ script = { common = tests/grub_script_gettext.in; }; +script = { + testcase; + name = grub_script_strcmp; + common = tests/grub_script_strcmp.in; +}; + program = { testcase; name = example_unit_test; @@ -713,6 +719,21 @@ program = { ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; +program = { + testcase; + name = cmp_test; + common = tests/cmp_unit_test.c; + common = tests/lib/unit_test.c; + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/tests/lib/test.c; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +}; + program = { name = grub-menulst2cfg; mansection = 1; diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 5635ebded..cd37b6448 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -532,6 +532,8 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, len = grub_be_to_cpu16 (catkey_a->namelen); if (len > catkey_b->namelen) len = catkey_b->namelen; + /* Since it's big-endian memcmp gives the same result as manually comparing + uint16_t but may be faster. */ diff = grub_memcmp (catkey_a->name, catkey_b->name, len * sizeof (catkey_a->name[0])); if (diff == 0) diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 164fd6e30..460ea10cd 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -216,8 +216,8 @@ grub_vprintf (const char *fmt, va_list args) int grub_memcmp (const void *s1, const void *s2, grub_size_t n) { - const char *t1 = s1; - const char *t2 = s2; + const grub_uint8_t *t1 = s1; + const grub_uint8_t *t2 = s2; while (n--) { @@ -252,7 +252,7 @@ grub_strcmp (const char *s1, const char *s2) s2++; } - return (int) *s1 - (int) *s2; + return (int) (grub_uint8_t) *s1 - (int) (grub_uint8_t) *s2; } int @@ -270,7 +270,7 @@ grub_strncmp (const char *s1, const char *s2, grub_size_t n) s2++; } - return (int) *s1 - (int) *s2; + return (int) (grub_uint8_t) *s1 - (int) (grub_uint8_t) *s2; } char * diff --git a/include/grub/misc.h b/include/grub/misc.h index a87c43691..ddc6329d6 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -247,14 +247,16 @@ grub_strcasecmp (const char *s1, const char *s2) { while (*s1 && *s2) { - if (grub_tolower (*s1) != grub_tolower (*s2)) + if (grub_tolower ((grub_uint8_t) *s1) + != grub_tolower ((grub_uint8_t) *s2)) break; s1++; s2++; } - return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); + return (int) grub_tolower ((grub_uint8_t) *s1) + - (int) grub_tolower ((grub_uint8_t) *s2); } static inline int @@ -272,7 +274,8 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) s2++; } - return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); + return (int) grub_tolower ((grub_uint8_t) *s1) + - (int) grub_tolower ((grub_uint8_t) *s2); } unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); diff --git a/tests/cmp_unit_test.c b/tests/cmp_unit_test.c new file mode 100644 index 000000000..6ca22816e --- /dev/null +++ b/tests/cmp_unit_test.c @@ -0,0 +1,224 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Functional test main method. */ +static void +cmp_test (void) +{ + const char *s1 = "a"; + const char *s2 = "aa"; + const char *s3 = "â"; + + grub_test_assert (grub_strlen (s1) == 1); + grub_test_assert (grub_strlen (s2) == 2); + grub_test_assert (grub_strlen (s3) == 2); + + grub_test_assert (grub_strcmp (s1, s1) == 0); + grub_test_assert (grub_strcmp (s1, s2) < 0); + grub_test_assert (grub_strcmp (s1, s3) < 0); + + grub_test_assert (grub_strcmp (s2, s1) > 0); + grub_test_assert (grub_strcmp (s2, s2) == 0); + grub_test_assert (grub_strcmp (s2, s3) < 0); + + grub_test_assert (grub_strcmp (s3, s1) > 0); + grub_test_assert (grub_strcmp (s3, s2) > 0); + grub_test_assert (grub_strcmp (s3, s3) == 0); + + grub_test_assert (grub_strcasecmp (s1, s1) == 0); + grub_test_assert (grub_strcasecmp (s1, s2) < 0); + grub_test_assert (grub_strcasecmp (s1, s3) < 0); + + grub_test_assert (grub_strcasecmp (s2, s1) > 0); + grub_test_assert (grub_strcasecmp (s2, s2) == 0); + grub_test_assert (grub_strcasecmp (s2, s3) < 0); + + grub_test_assert (grub_strcasecmp (s3, s1) > 0); + grub_test_assert (grub_strcasecmp (s3, s2) > 0); + grub_test_assert (grub_strcasecmp (s3, s3) == 0); + + grub_test_assert (grub_memcmp (s1, s1, 2) == 0); + grub_test_assert (grub_memcmp (s1, s2, 2) < 0); + grub_test_assert (grub_memcmp (s1, s3, 2) < 0); + + grub_test_assert (grub_memcmp (s2, s1, 2) > 0); + grub_test_assert (grub_memcmp (s2, s2, 2) == 0); + grub_test_assert (grub_memcmp (s2, s3, 2) < 0); + + grub_test_assert (grub_memcmp (s3, s1, 2) > 0); + grub_test_assert (grub_memcmp (s3, s2, 2) > 0); + grub_test_assert (grub_memcmp (s3, s3, 2) == 0); + + grub_test_assert (grub_memcmp (s1, s1, 1) == 0); + grub_test_assert (grub_memcmp (s1, s2, 1) == 0); + grub_test_assert (grub_memcmp (s1, s3, 1) < 0); + + grub_test_assert (grub_memcmp (s2, s1, 1) == 0); + grub_test_assert (grub_memcmp (s2, s2, 1) == 0); + grub_test_assert (grub_memcmp (s2, s3, 1) < 0); + + grub_test_assert (grub_memcmp (s3, s1, 1) > 0); + grub_test_assert (grub_memcmp (s3, s2, 1) > 0); + grub_test_assert (grub_memcmp (s3, s3, 1) == 0); + + grub_test_assert (grub_strncmp (s1, s1, 2) == 0); + grub_test_assert (grub_strncmp (s1, s2, 2) < 0); + grub_test_assert (grub_strncmp (s1, s3, 2) < 0); + + grub_test_assert (grub_strncmp (s2, s1, 2) > 0); + grub_test_assert (grub_strncmp (s2, s2, 2) == 0); + grub_test_assert (grub_strncmp (s2, s3, 2) < 0); + + grub_test_assert (grub_strncmp (s3, s1, 2) > 0); + grub_test_assert (grub_strncmp (s3, s2, 2) > 0); + grub_test_assert (grub_strncmp (s3, s3, 2) == 0); + + grub_test_assert (grub_strncmp (s1, s1, 1) == 0); + grub_test_assert (grub_strncmp (s1, s2, 1) == 0); + grub_test_assert (grub_strncmp (s1, s3, 1) < 0); + + grub_test_assert (grub_strncmp (s2, s1, 1) == 0); + grub_test_assert (grub_strncmp (s2, s2, 1) == 0); + grub_test_assert (grub_strncmp (s2, s3, 1) < 0); + + grub_test_assert (grub_strncmp (s3, s1, 1) > 0); + grub_test_assert (grub_strncmp (s3, s2, 1) > 0); + grub_test_assert (grub_strncmp (s3, s3, 1) == 0); + + grub_test_assert (grub_strncasecmp (s1, s1, 2) == 0); + grub_test_assert (grub_strncasecmp (s1, s2, 2) < 0); + grub_test_assert (grub_strncasecmp (s1, s3, 2) < 0); + + grub_test_assert (grub_strncasecmp (s2, s1, 2) > 0); + grub_test_assert (grub_strncasecmp (s2, s2, 2) == 0); + grub_test_assert (grub_strncasecmp (s2, s3, 2) < 0); + + grub_test_assert (grub_strncasecmp (s3, s1, 2) > 0); + grub_test_assert (grub_strncasecmp (s3, s2, 2) > 0); + grub_test_assert (grub_strncasecmp (s3, s3, 2) == 0); + + grub_test_assert (grub_strncasecmp (s1, s1, 1) == 0); + grub_test_assert (grub_strncasecmp (s1, s2, 1) == 0); + grub_test_assert (grub_strncasecmp (s1, s3, 1) < 0); + + grub_test_assert (grub_strncasecmp (s2, s1, 1) == 0); + grub_test_assert (grub_strncasecmp (s2, s2, 1) == 0); + grub_test_assert (grub_strncasecmp (s2, s3, 1) < 0); + + grub_test_assert (grub_strncasecmp (s3, s1, 1) > 0); + grub_test_assert (grub_strncasecmp (s3, s2, 1) > 0); + grub_test_assert (grub_strncasecmp (s3, s3, 1) == 0); + + grub_test_assert (strlen (s1) == 1); + grub_test_assert (strlen (s2) == 2); + grub_test_assert (strlen (s3) == 2); + + grub_test_assert (strcmp (s1, s1) == 0); + grub_test_assert (strcmp (s1, s2) < 0); + grub_test_assert (strcmp (s1, s3) < 0); + + grub_test_assert (strcmp (s2, s1) > 0); + grub_test_assert (strcmp (s2, s2) == 0); + grub_test_assert (strcmp (s2, s3) < 0); + + grub_test_assert (strcmp (s3, s1) > 0); + grub_test_assert (strcmp (s3, s2) > 0); + grub_test_assert (strcmp (s3, s3) == 0); + + grub_test_assert (memcmp (s1, s1, 2) == 0); + grub_test_assert (memcmp (s1, s2, 2) < 0); + grub_test_assert (memcmp (s1, s3, 2) < 0); + + grub_test_assert (memcmp (s2, s1, 2) > 0); + grub_test_assert (memcmp (s2, s2, 2) == 0); + grub_test_assert (memcmp (s2, s3, 2) < 0); + + grub_test_assert (memcmp (s3, s1, 2) > 0); + grub_test_assert (memcmp (s3, s2, 2) > 0); + grub_test_assert (memcmp (s3, s3, 2) == 0); + + grub_test_assert (memcmp (s1, s1, 1) == 0); + grub_test_assert (memcmp (s1, s2, 1) == 0); + grub_test_assert (memcmp (s1, s3, 1) < 0); + + grub_test_assert (memcmp (s2, s1, 1) == 0); + grub_test_assert (memcmp (s2, s2, 1) == 0); + grub_test_assert (memcmp (s2, s3, 1) < 0); + + grub_test_assert (memcmp (s3, s1, 1) > 0); + grub_test_assert (memcmp (s3, s2, 1) > 0); + grub_test_assert (memcmp (s3, s3, 1) == 0); + + grub_test_assert (strncmp (s1, s1, 2) == 0); + grub_test_assert (strncmp (s1, s2, 2) < 0); + grub_test_assert (strncmp (s1, s3, 2) < 0); + + grub_test_assert (strncmp (s2, s1, 2) > 0); + grub_test_assert (strncmp (s2, s2, 2) == 0); + grub_test_assert (strncmp (s2, s3, 2) < 0); + + grub_test_assert (strncmp (s3, s1, 2) > 0); + grub_test_assert (strncmp (s3, s2, 2) > 0); + grub_test_assert (strncmp (s3, s3, 2) == 0); + + grub_test_assert (strncmp (s1, s1, 1) == 0); + grub_test_assert (strncmp (s1, s2, 1) == 0); + grub_test_assert (strncmp (s1, s3, 1) < 0); + + grub_test_assert (strncmp (s2, s1, 1) == 0); + grub_test_assert (strncmp (s2, s2, 1) == 0); + grub_test_assert (strncmp (s2, s3, 1) < 0); + + grub_test_assert (strncmp (s3, s1, 1) > 0); + grub_test_assert (strncmp (s3, s2, 1) > 0); + grub_test_assert (strncmp (s3, s3, 1) == 0); + + grub_test_assert (strncasecmp (s1, s1, 2) == 0); + grub_test_assert (strncasecmp (s1, s2, 2) < 0); + grub_test_assert (strncasecmp (s1, s3, 2) < 0); + + grub_test_assert (strncasecmp (s2, s1, 2) > 0); + grub_test_assert (strncasecmp (s2, s2, 2) == 0); + grub_test_assert (strncasecmp (s2, s3, 2) < 0); + + grub_test_assert (strncasecmp (s3, s1, 2) > 0); + grub_test_assert (strncasecmp (s3, s2, 2) > 0); + grub_test_assert (strncasecmp (s3, s3, 2) == 0); + + grub_test_assert (strncasecmp (s1, s1, 1) == 0); + grub_test_assert (strncasecmp (s1, s2, 1) == 0); + grub_test_assert (strncasecmp (s1, s3, 1) < 0); + + grub_test_assert (strncasecmp (s2, s1, 1) == 0); + grub_test_assert (strncasecmp (s2, s2, 1) == 0); + grub_test_assert (strncasecmp (s2, s3, 1) < 0); + + grub_test_assert (strncasecmp (s3, s1, 1) > 0); + grub_test_assert (strncasecmp (s3, s2, 1) > 0); + grub_test_assert (strncasecmp (s3, s3, 1) == 0); +} + +/* Register example_test method as a functional test. */ +GRUB_UNIT_TEST ("cmp_test", cmp_test); diff --git a/tests/grub_script_strcmp.in b/tests/grub_script_strcmp.in new file mode 100644 index 000000000..721549ced --- /dev/null +++ b/tests/grub_script_strcmp.in @@ -0,0 +1,22 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +LC_ALL=C +export LC_ALL + +if [ "z" "<" "â" ]; then echo unsigned; else echo signed; fi +if [ "z" ">" "â" ]; then echo signed; else echo unsigned; fi