about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2018-07-20 11:58:51 +0200
committerFlorian Weimer <fweimer@redhat.com>2018-07-20 11:58:51 +0200
commit786658a08829e8a303d846406812f9245846e99c (patch)
treef29b3d0d1271d0a1c9555fce35a906388ac783e5
parent2d5c41ded92bf1247ba2a29ad2074cf79dc15669 (diff)
downloadglibc-786658a08829e8a303d846406812f9245846e99c.tar.gz
glibc-786658a08829e8a303d846406812f9245846e99c.tar.xz
glibc-786658a08829e8a303d846406812f9245846e99c.zip
regcomp: Fix off-by-one bug in build_equiv_class [BZ #23396]
This bug is very similar to bug 23036: The existing code assumed that
the length count included the length byte itself.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
-rw-r--r--ChangeLog6
-rw-r--r--posix/regcomp.c16
2 files changed, 10 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index b45c83ba2b..49d1377c68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-20  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #23396]
+	* posix/regcomp.c (build_equiv_class): When comparing weights, do
+	not compare an extra byte after the end of the weights.
+
 2018-07-20  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
 	* sysdeps/mach/hurd/i386/tls.h (_hurd_tls_init): Set multiple_threads
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 7b5ddaad0c..545d188468 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -3531,18 +3531,10 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
 	    continue;
 	  /* Compare only if the length matches and the collation rule
 	     index is the same.  */
-	  if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
-	    {
-	      int cnt = 0;
-
-	      while (cnt <= len &&
-		     weights[(idx1 & 0xffffff) + 1 + cnt]
-		     == weights[(idx2 & 0xffffff) + 1 + cnt])
-		++cnt;
-
-	      if (cnt > len)
-		bitset_set (sbcset, ch);
-	    }
+	  if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)
+	      && memcmp (weights + (idx1 & 0xffffff) + 1,
+			 weights + (idx2 & 0xffffff) + 1, len) == 0)
+	    bitset_set (sbcset, ch);
 	}
       /* Check whether the array has enough space.  */
       if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))