On Sat, Oct 01, 2005 at 01:29:10PM +0200, Denis Barbier wrote:
> I was eventually able to test this patch.  Eugeniy's test case still
> segfaults, I will work on a better patch, strcoll_l.c needs to be
> fixed too.

Here is a revised patch.  It seems to work fine, but it has not been
fully tested yet.  I send it in case someone is working on this bug
report, and will add the patch tag after more testing.

Denis
#! /bin/sh -e

# DP: Description: Fix segfault when strings contain a mix of forward
#     and backward rules.
# DP: Dpatch Author: Denis Barbier <[EMAIL PROTECTED]>
# DP: Patch Author: Denis Barbier
# DP: Upstream status: Unknown
# DP: Date: 2005-10-01

if [ $# -ne 2 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
    -unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

--- glibc-2.3.3-net/string/strxfrm_l.c  14 Mar 2004 20:52:47 -0000      1.4
+++ glibc-2.3.3-net/string/strxfrm_l.c  23 May 2005 22:35:59 -0000
@@ -210,18 +210,19 @@
                      /* Handle the pushed elements now.  */
                      size_t backw;
 
-                     for (backw = idxcnt - 1; backw >= backw_stop; --backw)
+                     /* Take care of integer overflow if backw_stop is 0.  */
+                     for (backw = idxcnt; backw > backw_stop; --backw)
                        {
-                         len = weights[idxarr[backw]++];
+                         len = weights[idxarr[backw - 1]++];
 
                          if (needed + len < n)
                            while (len-- > 0)
-                             dest[needed++] = weights[idxarr[backw]++];
+                             dest[needed++] = weights[idxarr[backw - 1]++];
                          else
                            {
                                /* No more characters fit into the buffer.  */
                              needed += len;
-                             idxarr[backw] += len;
+                             idxarr[backw - 1] += len;
                            }
                        }
 
@@ -293,9 +294,10 @@
                     /* Handle the pushed elements now.  */
                      size_t backw;
 
-                     for (backw = idxcnt - 1; backw >= backw_stop; --backw)
+                     /* Take care of integer overflow if backw_stop is 0.  */
+                     for (backw = idxcnt; backw > backw_stop; --backw)
                        {
-                         len = weights[idxarr[backw]++];
+                         len = weights[idxarr[backw - 1]++];
                          if (len != 0)
                            {
 #ifdef WIDE_CHAR_VERSION
@@ -304,7 +306,7 @@
                                  dest[needed] = val;
                                  for (i = 0; i < len; ++i)
                                    dest[needed + 1 + i] =
-                                     weights[idxarr[backw] + i];
+                                     weights[idxarr[backw - 1] + i];
                                }
                              needed += 1 + len;
 #else
@@ -315,11 +317,11 @@
                                    dest[needed + i] = buf[i];
                                  for (i = 0; i < len; ++i)
                                    dest[needed + buflen + i] =
-                                     weights[idxarr[backw] + i];
+                                     weights[idxarr[backw - 1] + i];
                                }
                              needed += buflen + len;
 #endif
-                             idxarr[backw] += len;
+                             idxarr[backw - 1] += len;
                              val = 1;
                            }
                          else
--- glibc-2.3.3-net/string/strcoll_l.c  14 Mar 2004 20:52:47 -0000      1.4
+++ glibc-2.3.3-net/string/strcoll_l.c  23 May 2005 22:35:59 -0000
@@ -370,7 +370,10 @@
                        /* The last pushed character was handled.  Continue
                           with forward characters.  */
                        if (idx1cnt < idx1max)
-                         idx1now = idx1cnt;
+                         {
+                           idx1now = idx1cnt;
+                           backw1_stop = ~0ul;
+                         }
                        else
                          {
                            /* Nothing anymore.  The backward sequence

Reply via email to