diff mbox

string: Additional test for strcmp, strcasecmp

Message ID 20160705121916.AEF964025EC44@oldenburg.str.redhat.com
State Superseded
Headers show

Commit Message

Florian Weimer July 5, 2016, 12:19 p.m. UTC
2016-07-05  Florian Weimer  <fweimer@redhat.com>

	* string/tst-cmp.c: New test.
	* string/Makefile (tests): Add it.

Comments

Rajalakshmi S July 7, 2016, 4:06 p.m. UTC | #1
On 07/05/2016 05:49 PM, Florian Weimer wrote:
> 2016-07-05  Florian Weimer  <fweimer@redhat.com>
>
> 	* string/tst-cmp.c: New test.
> 	* string/Makefile (tests): Add it.
LGTM. Just one comment.
Can you include strncmp and strncasecmp as well?
>
Florian Weimer July 7, 2016, 4:16 p.m. UTC | #2
On 07/07/2016 06:06 PM, Rajalakshmi Srinivasaraghavan wrote:
>
>
> On 07/05/2016 05:49 PM, Florian Weimer wrote:
>> 2016-07-05  Florian Weimer  <fweimer@redhat.com>
>>
>>     * string/tst-cmp.c: New test.
>>     * string/Makefile (tests): Add it.

> LGTM. Just one comment.

Thanks.

> Can you include strncmp and strncasecmp as well?

What shall we do about the length argument?  Keep it constant at 64 or 
something like that?

Florian
Rajalakshmi S July 7, 2016, 4:25 p.m. UTC | #3
On 07/07/2016 09:46 PM, Florian Weimer wrote:
> On 07/07/2016 06:06 PM, Rajalakshmi Srinivasaraghavan wrote:
>>
>>
>> On 07/05/2016 05:49 PM, Florian Weimer wrote:
>>> 2016-07-05  Florian Weimer <fweimer@redhat.com>
>>>
>>>     * string/tst-cmp.c: New test.
>>>     * string/Makefile (tests): Add it.
>
>> LGTM. Just one comment.
>
> Thanks.
>
>> Can you include strncmp and strncasecmp as well?
>
> What shall we do about the length argument?  Keep it constant at 64 or 
> something like that?
Either constant or strlen(left + left_align)+1.
>
> Florian
>
>
Florian Weimer July 7, 2016, 4:50 p.m. UTC | #4
On 07/07/2016 06:25 PM, Rajalakshmi Srinivasaraghavan wrote:
>
>
> On 07/07/2016 09:46 PM, Florian Weimer wrote:
>> On 07/07/2016 06:06 PM, Rajalakshmi Srinivasaraghavan wrote:
>>>
>>>
>>> On 07/05/2016 05:49 PM, Florian Weimer wrote:
>>>> 2016-07-05  Florian Weimer <fweimer@redhat.com>
>>>>
>>>>     * string/tst-cmp.c: New test.
>>>>     * string/Makefile (tests): Add it.
>>
>>> LGTM. Just one comment.
>>
>> Thanks.
>>
>>> Can you include strncmp and strncasecmp as well?
>>
>> What shall we do about the length argument?  Keep it constant at 64 or
>> something like that?

> Either constant or strlen(left + left_align)+1.

That alters the result of the comparison.  We would have to use the 
maximum over both string lengths, I think.

Florian
diff mbox

Patch

diff --git a/string/Makefile b/string/Makefile
index 9c87419..69d3f80 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -54,7 +54,7 @@  tests		:= tester inl-tester noinl-tester testcopy test-ffs	\
 		   tst-strtok tst-strxfrm bug-strcoll1 tst-strfry	\
 		   bug-strtok1 $(addprefix test-,$(strop-tests))	\
 		   bug-envz1 tst-strxfrm2 tst-endian tst-svc2		\
-		   tst-strtok_r bug-strcoll2
+		   tst-strtok_r bug-strcoll2 tst-cmp
 
 xtests = tst-strcoll-overflow
 
diff --git a/string/tst-cmp.c b/string/tst-cmp.c
new file mode 100644
index 0000000..3e0e60c
--- /dev/null
+++ b/string/tst-cmp.c
@@ -0,0 +1,119 @@ 
+/* Alignment/padding coverage test for strcmp, strcasecmp.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This performs test comparisons with various (mis)alignments and
+   characters in the padding.  It is partly a regression test for
+   bug 20327.  */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <malloc.h>
+#include <locale.h>
+
+static int
+signum (int val)
+{
+  if (val < 0)
+    return -1;
+  if (val > 0)
+    return 1;
+  else
+    return 0;
+}
+
+static int
+do_test (void)
+{
+  enum {
+    max_align = 64,
+    max_string_length = 33
+  };
+  size_t blob_size = max_align + max_string_length + 1;
+  char *left = memalign (max_align, blob_size);
+  char *right = memalign (max_align, blob_size);
+  if (left == NULL || right == NULL)
+    {
+      printf ("error: out of memory\n");
+      return 1;
+    }
+
+  const char *funcs[2] = { "strcmp", "strcasecmp" };
+  const char *const strings[] =
+    {
+      "",
+      "0",
+      "01234567",
+      "0123456789abcde",
+      "0123456789abcdef",
+      "0123456789abcdefg",
+      "123456789abcdef",
+      "abcdefghijklmnopqrstuvwxyzABCDEF",
+      NULL
+    };
+  const unsigned char pads[] =
+    { 0, 1, 32, 64, 128, 48, 63, 127, 192, 255 };
+
+  bool errors = false;
+  for (int use_casecmp = 0; use_casecmp < 2; ++use_casecmp)
+    for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx)
+      for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left)
+        for (int left_align = 0; left_align < max_align; ++left_align)
+          {
+            memset (left, pads[pad_left], blob_size);
+            strcpy (left + left_align, strings[left_idx]);
+            for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx)
+              for (unsigned pad_right = 0; pad_right < sizeof (pads);
+                   ++pad_right)
+                for (int right_align = 0; right_align < max_align;
+                     ++right_align)
+                  {
+                    memset (right, pads[pad_right], blob_size);
+                    strcpy (right + right_align, strings[right_idx]);
+
+                    int expected = left_idx - right_idx;
+                    int actual;
+                    if (use_casecmp)
+                        actual = strcasecmp (left + left_align,
+                                             right + right_align);
+                    else
+                      actual = strcmp (left + left_align,
+                                       right + right_align);
+
+                    if (signum (actual) != signum (expected))
+                      {
+                        printf ("error: mismatch for %s: %d\n"
+                                "  left:  \"%s\"\n"
+                                "  right: \"%s\"\n"
+                                "  pad_left = %u, pad_right = %u,\n"
+                                "  left_align = %d, right_align = %d\n",
+                                funcs[use_casecmp], actual,
+                                strings[left_idx], strings[right_idx],
+                                pad_left, pad_right, left_align, right_align);
+                        errors = true;
+                      }
+                  }
+          }
+
+  free (right);
+  free (left);
+  return errors;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"