emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r115168: Fix recently introduced bool vector overrun


From: Paul Eggert
Subject: [Emacs-diffs] trunk r115168: Fix recently introduced bool vector overrun.
Date: Thu, 21 Nov 2013 06:47:20 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 115168
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Wed 2013-11-20 22:46:59 -0800
message:
  Fix recently introduced bool vector overrun.
  
  This was due to an optimization that went awry.
  Reported by Glenn Morris in
  <http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00622.html>.
  * alloc.c (make_uninit_bool_vector): Don't allocate a dummy word
  for empty vectors, undoing the 2013-11-18 change.
  * data.c (bool_vector_binop_driver): Rely on this.
  Fix bug that occasionally overran the destination.
  * lisp.h (struct Lisp_Bool_vector): Document this.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/alloc.c                    alloc.c-20091113204419-o5vbwnq5f7feedwu-252
  src/data.c                     data.c-20091113204419-o5vbwnq5f7feedwu-251
  src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-11-20 18:33:12 +0000
+++ b/src/ChangeLog     2013-11-21 06:46:59 +0000
@@ -1,3 +1,15 @@
+2013-11-21  Paul Eggert  <address@hidden>
+
+       Fix recently introduced bool vector overrun.
+       This was due to an optimization that went awry.
+       Reported by Glenn Morris in
+       <http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00622.html>.
+       * alloc.c (make_uninit_bool_vector): Don't allocate a dummy word
+       for empty vectors, undoing the 2013-11-18 change.
+       * data.c (bool_vector_binop_driver): Rely on this.
+       Fix bug that occasionally overran the destination.
+       * lisp.h (struct Lisp_Bool_vector): Document this.
+
 2013-11-20  Jan Djärv  <address@hidden>
 
        * nsterm.m (init, run, stop:): Enable again. stop calls super stop

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2013-11-18 18:37:25 +0000
+++ b/src/alloc.c       2013-11-21 06:46:59 +0000
@@ -2066,8 +2066,7 @@
 make_uninit_bool_vector (EMACS_INT nbits)
 {
   Lisp_Object val;
-  EMACS_INT words0 = bool_vector_words (nbits);
-  EMACS_INT words = words0 + !words0;  /* Allocate at least one word.  */
+  EMACS_INT words = bool_vector_words (nbits);
   EMACS_INT word_bytes = words * sizeof (bits_word);
   EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
                                + word_size - 1)
@@ -2078,9 +2077,9 @@
   XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
   p->size = nbits;
 
-  /* Clear padding at the end.  If NBITS != 0 this initializes more
-     than it needs to, but that's OK.  */
-  p->data[words - 1] = 0;
+  /* Clear padding at the end.  */
+  if (words)
+    p->data[words - 1] = 0;
 
   return val;
 }

=== modified file 'src/data.c'
--- a/src/data.c        2013-11-18 19:31:05 +0000
+++ b/src/data.c        2013-11-21 06:46:59 +0000
@@ -3054,60 +3054,64 @@
       switch (op)
        {
        case bool_vector_exclusive_or:
-         while (destdata[i] == (adata[i] ^ bdata[i]))
-           if (! (++i < nr_words))
-             return Qnil;
+         for (; i < nr_words; i++)
+           if (destdata[i] != (adata[i] ^ bdata[i]))
+             goto set_dest;
          break;
 
        case bool_vector_subsetp:
+         for (; i < nr_words; i++)
+           if (adata[i] &~ bdata[i])
+             return Qnil;
+         return Qt;
+
        case bool_vector_union:
-         while (destdata[i] == (adata[i] | bdata[i]))
-           if (! (++i < nr_words))
-             return Qnil;
+         for (; i < nr_words; i++)
+           if (destdata[i] != (adata[i] | bdata[i]))
+             goto set_dest;
          break;
 
        case bool_vector_intersection:
-         while (destdata[i] == (adata[i] & bdata[i]))
-           if (! (++i < nr_words))
-             return Qnil;
+         for (; i < nr_words; i++)
+           if (destdata[i] != (adata[i] & bdata[i]))
+             goto set_dest;
          break;
 
        case bool_vector_set_difference:
-         while (destdata[i] == (adata[i] &~ bdata[i]))
-           if (! (++i < nr_words))
-             return Qnil;
+         for (; i < nr_words; i++)
+           if (destdata[i] != (adata[i] &~ bdata[i]))
+             goto set_dest;
          break;
        }
+
+      return Qnil;
     }
 
+ set_dest:
   switch (op)
     {
     case bool_vector_exclusive_or:
-      do
+      for (; i < nr_words; i++)
        destdata[i] = adata[i] ^ bdata[i];
-      while (++i < nr_words);
-      break;
-
-    case bool_vector_subsetp:
       break;
 
     case bool_vector_union:
-      do
+      for (; i < nr_words; i++)
        destdata[i] = adata[i] | bdata[i];
-      while (++i < nr_words);
       break;
 
     case bool_vector_intersection:
-      do
+      for (; i < nr_words; i++)
        destdata[i] = adata[i] & bdata[i];
-      while (++i < nr_words);
       break;
 
     case bool_vector_set_difference:
-      do
+      for (; i < nr_words; i++)
        destdata[i] = adata[i] &~ bdata[i];
-      while (++i < nr_words);
       break;
+
+    default:
+      eassume (0);
     }
 
   return dest;

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2013-11-18 18:37:25 +0000
+++ b/src/lisp.h        2013-11-21 06:46:59 +0000
@@ -1213,7 +1213,7 @@
     /* This is the size in bits.  */
     EMACS_INT size;
     /* The actual bits, packed into bytes.
-       Zeros fill out the last word as needed; there's always at least one 
word.
+       Zeros fill out the last word if needed.
        The bits are in little-endian order in the bytes, and
        the bytes are in little-endian order in the words.  */
     bits_word data[FLEXIBLE_ARRAY_MEMBER];


reply via email to

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