aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-11-20 22:46:59 -0800
committerPaul Eggert2013-11-20 22:46:59 -0800
commit75360f19c3994ab7a532124b7f5eb92bfe7c82ed (patch)
treeed6a415b319a37144d63bdfe967daff766f4e044 /src
parentd1a6bccc995f7e1e9d22a386e1aac0d7c888ff18 (diff)
downloademacs-75360f19c3994ab7a532124b7f5eb92bfe7c82ed.tar.gz
emacs-75360f19c3994ab7a532124b7f5eb92bfe7c82ed.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/alloc.c9
-rw-r--r--src/data.c50
-rw-r--r--src/lisp.h2
4 files changed, 44 insertions, 29 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e0ac7f298c7..925f6389bf8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
12013-11-21 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix recently introduced bool vector overrun.
4 This was due to an optimization that went awry.
5 Reported by Glenn Morris in
6 <http://lists.gnu.org/archive/html/emacs-devel/2013-11/msg00622.html>.
7 * alloc.c (make_uninit_bool_vector): Don't allocate a dummy word
8 for empty vectors, undoing the 2013-11-18 change.
9 * data.c (bool_vector_binop_driver): Rely on this.
10 Fix bug that occasionally overran the destination.
11 * lisp.h (struct Lisp_Bool_vector): Document this.
12
12013-11-20 Jan Djärv <jan.h.d@swipnet.se> 132013-11-20 Jan Djärv <jan.h.d@swipnet.se>
2 14
3 * nsterm.m (init, run, stop:): Enable again. stop calls super stop 15 * nsterm.m (init, run, stop:): Enable again. stop calls super stop
diff --git a/src/alloc.c b/src/alloc.c
index 7c560fd0f0d..283bc613c82 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2066,8 +2066,7 @@ Lisp_Object
2066make_uninit_bool_vector (EMACS_INT nbits) 2066make_uninit_bool_vector (EMACS_INT nbits)
2067{ 2067{
2068 Lisp_Object val; 2068 Lisp_Object val;
2069 EMACS_INT words0 = bool_vector_words (nbits); 2069 EMACS_INT words = bool_vector_words (nbits);
2070 EMACS_INT words = words0 + !words0; /* Allocate at least one word. */
2071 EMACS_INT word_bytes = words * sizeof (bits_word); 2070 EMACS_INT word_bytes = words * sizeof (bits_word);
2072 EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes 2071 EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
2073 + word_size - 1) 2072 + word_size - 1)
@@ -2078,9 +2077,9 @@ make_uninit_bool_vector (EMACS_INT nbits)
2078 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); 2077 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2079 p->size = nbits; 2078 p->size = nbits;
2080 2079
2081 /* Clear padding at the end. If NBITS != 0 this initializes more 2080 /* Clear padding at the end. */
2082 than it needs to, but that's OK. */ 2081 if (words)
2083 p->data[words - 1] = 0; 2082 p->data[words - 1] = 0;
2084 2083
2085 return val; 2084 return val;
2086} 2085}
diff --git a/src/data.c b/src/data.c
index 33dd11049ec..bdd56bf0f62 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3054,60 +3054,64 @@ bool_vector_binop_driver (Lisp_Object a,
3054 switch (op) 3054 switch (op)
3055 { 3055 {
3056 case bool_vector_exclusive_or: 3056 case bool_vector_exclusive_or:
3057 while (destdata[i] == (adata[i] ^ bdata[i])) 3057 for (; i < nr_words; i++)
3058 if (! (++i < nr_words)) 3058 if (destdata[i] != (adata[i] ^ bdata[i]))
3059 return Qnil; 3059 goto set_dest;
3060 break; 3060 break;
3061 3061
3062 case bool_vector_subsetp: 3062 case bool_vector_subsetp:
3063 case bool_vector_union: 3063 for (; i < nr_words; i++)
3064 while (destdata[i] == (adata[i] | bdata[i])) 3064 if (adata[i] &~ bdata[i])
3065 if (! (++i < nr_words))
3066 return Qnil; 3065 return Qnil;
3066 return Qt;
3067
3068 case bool_vector_union:
3069 for (; i < nr_words; i++)
3070 if (destdata[i] != (adata[i] | bdata[i]))
3071 goto set_dest;
3067 break; 3072 break;
3068 3073
3069 case bool_vector_intersection: 3074 case bool_vector_intersection:
3070 while (destdata[i] == (adata[i] & bdata[i])) 3075 for (; i < nr_words; i++)
3071 if (! (++i < nr_words)) 3076 if (destdata[i] != (adata[i] & bdata[i]))
3072 return Qnil; 3077 goto set_dest;
3073 break; 3078 break;
3074 3079
3075 case bool_vector_set_difference: 3080 case bool_vector_set_difference:
3076 while (destdata[i] == (adata[i] &~ bdata[i])) 3081 for (; i < nr_words; i++)
3077 if (! (++i < nr_words)) 3082 if (destdata[i] != (adata[i] &~ bdata[i]))
3078 return Qnil; 3083 goto set_dest;
3079 break; 3084 break;
3080 } 3085 }
3086
3087 return Qnil;
3081 } 3088 }
3082 3089
3090 set_dest:
3083 switch (op) 3091 switch (op)
3084 { 3092 {
3085 case bool_vector_exclusive_or: 3093 case bool_vector_exclusive_or:
3086 do 3094 for (; i < nr_words; i++)
3087 destdata[i] = adata[i] ^ bdata[i]; 3095 destdata[i] = adata[i] ^ bdata[i];
3088 while (++i < nr_words);
3089 break;
3090
3091 case bool_vector_subsetp:
3092 break; 3096 break;
3093 3097
3094 case bool_vector_union: 3098 case bool_vector_union:
3095 do 3099 for (; i < nr_words; i++)
3096 destdata[i] = adata[i] | bdata[i]; 3100 destdata[i] = adata[i] | bdata[i];
3097 while (++i < nr_words);
3098 break; 3101 break;
3099 3102
3100 case bool_vector_intersection: 3103 case bool_vector_intersection:
3101 do 3104 for (; i < nr_words; i++)
3102 destdata[i] = adata[i] & bdata[i]; 3105 destdata[i] = adata[i] & bdata[i];
3103 while (++i < nr_words);
3104 break; 3106 break;
3105 3107
3106 case bool_vector_set_difference: 3108 case bool_vector_set_difference:
3107 do 3109 for (; i < nr_words; i++)
3108 destdata[i] = adata[i] &~ bdata[i]; 3110 destdata[i] = adata[i] &~ bdata[i];
3109 while (++i < nr_words);
3110 break; 3111 break;
3112
3113 default:
3114 eassume (0);
3111 } 3115 }
3112 3116
3113 return dest; 3117 return dest;
diff --git a/src/lisp.h b/src/lisp.h
index 8521c87e5d7..a9aac2cc0bb 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1213,7 +1213,7 @@ struct Lisp_Bool_Vector
1213 /* This is the size in bits. */ 1213 /* This is the size in bits. */
1214 EMACS_INT size; 1214 EMACS_INT size;
1215 /* The actual bits, packed into bytes. 1215 /* The actual bits, packed into bytes.
1216 Zeros fill out the last word as needed; there's always at least one word. 1216 Zeros fill out the last word if needed.
1217 The bits are in little-endian order in the bytes, and 1217 The bits are in little-endian order in the bytes, and
1218 the bytes are in little-endian order in the words. */ 1218 the bytes are in little-endian order in the words. */
1219 bits_word data[FLEXIBLE_ARRAY_MEMBER]; 1219 bits_word data[FLEXIBLE_ARRAY_MEMBER];