bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] fix infinite loop in mbmemcasecoll


From: Bruno Haible
Subject: Re: [PATCH] fix infinite loop in mbmemcasecoll
Date: Wed, 22 Sep 2010 13:37:59 +0200
User-agent: KMail/1.9.9

Hi Pádraig,

> I was testing multi-byte enhancements to coreutils/join with:
> LC_ALL=en_US.utf8 join -i <(env printf '1\x00\n') <(env printf '2\x00\n')
> and noticed it spun the CPU because of the NUL char.
> The attached fixes the issue for me. This function is supposed
> to skip over NUL chars like this right?

Right.

> --- a/lib/mbmemcasecoll.c     2010-01-04 01:10:30.000000000 +0000
> +++ b/lib/mbmemcasecoll.c     2010-09-21 23:52:23.000000000 +0000
> @@ -61,6 +63,8 @@
>          break;
>        if (n1 != (size_t)(-1))
>          {
> +          if (n1 == 0)
> +            n1 = 1; /* copy NUL characters.  */
>            wint_t wc2 = towlower (wc1);
> 
>            if (wc2 != wc1)

The patch is right, except that we stick with C89 syntax in gnulib: no
statements before declarations. I'm adding the fix and a test case:


2010-09-22  Pádraig Brady  <address@hidden>
            Bruno Haible  <address@hidden>

        Fix endless loop in mbmemcasecoll.
        * lib/mbmemcasecoll.c (apply_towlower): When mbrtowc returns 0, copy 1
        byte.
        * tests/test-mbmemcasecmp.h (test_ascii): Test embedded NULs.

--- lib/mbmemcasecoll.c.orig    Wed Sep 22 13:31:27 2010
+++ lib/mbmemcasecoll.c Wed Sep 22 13:30:00 2010
@@ -1,5 +1,5 @@
 /* Locale-specific case-ignoring memory comparison.
-   Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2009-2010 Free Software Foundation, Inc.
    Written by Bruno Haible <address@hidden>, 2001.
 
    This program is free software: you can redistribute it and/or modify it
@@ -61,8 +61,12 @@
         break;
       if (n1 != (size_t)(-1))
         {
-          wint_t wc2 = towlower (wc1);
+          wint_t wc2;
 
+          if (n1 == 0) /* NUL character? */
+            n1 = 1;
+
+          wc2 = towlower (wc1);
           if (wc2 != wc1)
             {
               size_t n2;
--- tests/test-mbmemcasecmp.h.orig      Wed Sep 22 13:31:27 2010
+++ tests/test-mbmemcasecmp.h   Wed Sep 22 13:21:32 2010
@@ -62,6 +62,12 @@
 
   ASSERT (my_casecmp ("para", 4, "paragraph", 9) < 0);
   ASSERT (my_casecmp ("paragraph", 9, "para", 4) > 0);
+
+  /* Embedded NULs.  */
+  ASSERT (my_casecmp ("1\0", 2, "2\0", 2) < 0);
+  ASSERT (my_casecmp ("2\0", 2, "1\0", 2) > 0);
+  ASSERT (my_casecmp ("x\0""1", 3, "x\0""2", 3) < 0);
+  ASSERT (my_casecmp ("x\0""2", 3, "x\0""1", 3) > 0);
 }
 
 static void



reply via email to

[Prev in Thread] Current Thread [Next in Thread]