diff options
| author | Paul Eggert | 2020-08-15 10:48:36 -0700 |
|---|---|---|
| committer | Paul Eggert | 2020-08-15 11:19:51 -0700 |
| commit | d0145537fa511a44e2a4af01da3947e92f0b8331 (patch) | |
| tree | 0b098e725155c3b40031e0ecb8c65bbb25a6e402 /src | |
| parent | 4cba236749aafade7bd88cf2a10be48f44983faa (diff) | |
| download | emacs-d0145537fa511a44e2a4af01da3947e92f0b8331.tar.gz emacs-d0145537fa511a44e2a4af01da3947e92f0b8331.zip | |
Fix GC bugs related to uninitialized vectors
Avoid problems if GC occurs while initializing a vector.
Problem with Fdelete reported by Pip Cet in:
https://lists.gnu.org/r/emacs-devel/2020-08/msg00313.html
I looked for similar problems elsewhere and found quite a few.
* src/coding.c (make_subsidiaries):
* src/composite.c (syms_of_composite):
* src/font.c (build_style_table, Ffont_get_glyphs):
* src/nsselect.m (clean_local_selection_data):
* src/nsxwidget.m (js_to_lisp):
* src/syntax.c (init_syntax_once):
* src/window.c (Fcurrent_window_configuration):
* src/xselect.c (selection_data_to_lisp_data)
(clean_local_selection_data):
Use make_nil_vector instead of make_uninit_vector.
* src/fns.c (Fdelete):
* src/xwidget.c (webkit_js_to_lisp):
Use allocate_nil_vector instead of allocate_vector.
* src/search.c (Fnewline_cache_check):
Use make_vector instead of make_uninit_vector.
Diffstat (limited to 'src')
| -rw-r--r-- | src/coding.c | 9 | ||||
| -rw-r--r-- | src/composite.c | 2 | ||||
| -rw-r--r-- | src/fns.c | 2 | ||||
| -rw-r--r-- | src/font.c | 6 | ||||
| -rw-r--r-- | src/lisp.h | 7 | ||||
| -rw-r--r-- | src/nsselect.m | 2 | ||||
| -rw-r--r-- | src/nsxwidget.m | 4 | ||||
| -rw-r--r-- | src/search.c | 9 | ||||
| -rw-r--r-- | src/syntax.c | 4 | ||||
| -rw-r--r-- | src/window.c | 2 | ||||
| -rw-r--r-- | src/xselect.c | 6 | ||||
| -rw-r--r-- | src/xwidget.c | 4 |
12 files changed, 26 insertions, 31 deletions
diff --git a/src/coding.c b/src/coding.c index 1d79c703a3a..51bd441de9d 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -10856,20 +10856,17 @@ HIGHESTP non-nil means just return the highest priority one. */) | |||
| 10856 | return Fnreverse (val); | 10856 | return Fnreverse (val); |
| 10857 | } | 10857 | } |
| 10858 | 10858 | ||
| 10859 | static const char *const suffixes[] = { "-unix", "-dos", "-mac" }; | ||
| 10860 | |||
| 10861 | static Lisp_Object | 10859 | static Lisp_Object |
| 10862 | make_subsidiaries (Lisp_Object base) | 10860 | make_subsidiaries (Lisp_Object base) |
| 10863 | { | 10861 | { |
| 10864 | Lisp_Object subsidiaries; | 10862 | static char const suffixes[][8] = { "-unix", "-dos", "-mac" }; |
| 10865 | ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base)); | 10863 | ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base)); |
| 10866 | USE_SAFE_ALLOCA; | 10864 | USE_SAFE_ALLOCA; |
| 10867 | char *buf = SAFE_ALLOCA (base_name_len + 6); | 10865 | char *buf = SAFE_ALLOCA (base_name_len + 6); |
| 10868 | int i; | ||
| 10869 | 10866 | ||
| 10870 | memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len); | 10867 | memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len); |
| 10871 | subsidiaries = make_uninit_vector (3); | 10868 | Lisp_Object subsidiaries = make_nil_vector (3); |
| 10872 | for (i = 0; i < 3; i++) | 10869 | for (int i = 0; i < 3; i++) |
| 10873 | { | 10870 | { |
| 10874 | strcpy (buf + base_name_len, suffixes[i]); | 10871 | strcpy (buf + base_name_len, suffixes[i]); |
| 10875 | ASET (subsidiaries, i, intern (buf)); | 10872 | ASET (subsidiaries, i, intern (buf)); |
diff --git a/src/composite.c b/src/composite.c index ec2b8328f78..396d456f8cb 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -1939,7 +1939,7 @@ syms_of_composite (void) | |||
| 1939 | staticpro (&gstring_hash_table); | 1939 | staticpro (&gstring_hash_table); |
| 1940 | 1940 | ||
| 1941 | staticpro (&gstring_work_headers); | 1941 | staticpro (&gstring_work_headers); |
| 1942 | gstring_work_headers = make_uninit_vector (8); | 1942 | gstring_work_headers = make_nil_vector (8); |
| 1943 | for (i = 0; i < 8; i++) | 1943 | for (i = 0; i < 8; i++) |
| 1944 | ASET (gstring_work_headers, i, make_nil_vector (i + 2)); | 1944 | ASET (gstring_work_headers, i, make_nil_vector (i + 2)); |
| 1945 | staticpro (&gstring_work); | 1945 | staticpro (&gstring_work); |
| @@ -1755,7 +1755,7 @@ changing the value of a sequence `foo'. */) | |||
| 1755 | 1755 | ||
| 1756 | if (n != ASIZE (seq)) | 1756 | if (n != ASIZE (seq)) |
| 1757 | { | 1757 | { |
| 1758 | struct Lisp_Vector *p = allocate_vector (n); | 1758 | struct Lisp_Vector *p = allocate_nil_vector (n); |
| 1759 | 1759 | ||
| 1760 | for (i = n = 0; i < ASIZE (seq); ++i) | 1760 | for (i = n = 0; i < ASIZE (seq); ++i) |
| 1761 | if (NILP (Fequal (AREF (seq, i), elt))) | 1761 | if (NILP (Fequal (AREF (seq, i), elt))) |
diff --git a/src/font.c b/src/font.c index ab00402b40b..ccbd3fc9ce6 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -4889,7 +4889,7 @@ the corresponding element is nil. */) | |||
| 4889 | { | 4889 | { |
| 4890 | struct font *font = CHECK_FONT_GET_OBJECT (font_object); | 4890 | struct font *font = CHECK_FONT_GET_OBJECT (font_object); |
| 4891 | ptrdiff_t len; | 4891 | ptrdiff_t len; |
| 4892 | Lisp_Object *chars, vec; | 4892 | Lisp_Object *chars; |
| 4893 | USE_SAFE_ALLOCA; | 4893 | USE_SAFE_ALLOCA; |
| 4894 | 4894 | ||
| 4895 | if (NILP (object)) | 4895 | if (NILP (object)) |
| @@ -4957,7 +4957,7 @@ the corresponding element is nil. */) | |||
| 4957 | else | 4957 | else |
| 4958 | wrong_type_argument (Qarrayp, object); | 4958 | wrong_type_argument (Qarrayp, object); |
| 4959 | 4959 | ||
| 4960 | vec = make_uninit_vector (len); | 4960 | Lisp_Object vec = make_nil_vector (len); |
| 4961 | for (ptrdiff_t i = 0; i < len; i++) | 4961 | for (ptrdiff_t i = 0; i < len; i++) |
| 4962 | { | 4962 | { |
| 4963 | Lisp_Object g; | 4963 | Lisp_Object g; |
| @@ -5203,7 +5203,7 @@ If the named font cannot be opened and loaded, return nil. */) | |||
| 5203 | static Lisp_Object | 5203 | static Lisp_Object |
| 5204 | build_style_table (const struct table_entry *entry, int nelement) | 5204 | build_style_table (const struct table_entry *entry, int nelement) |
| 5205 | { | 5205 | { |
| 5206 | Lisp_Object table = make_uninit_vector (nelement); | 5206 | Lisp_Object table = make_nil_vector (nelement); |
| 5207 | for (int i = 0; i < nelement; i++) | 5207 | for (int i = 0; i < nelement; i++) |
| 5208 | { | 5208 | { |
| 5209 | int j; | 5209 | int j; |
diff --git a/src/lisp.h b/src/lisp.h index eaf1c6ce6df..7983339ac50 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3916,7 +3916,6 @@ build_string (const char *str) | |||
| 3916 | 3916 | ||
| 3917 | extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); | 3917 | extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); |
| 3918 | extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object); | 3918 | extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object); |
| 3919 | extern struct Lisp_Vector *allocate_vector (ptrdiff_t); | ||
| 3920 | extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); | 3919 | extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); |
| 3921 | 3920 | ||
| 3922 | /* Make an uninitialized vector for SIZE objects. NOTE: you must | 3921 | /* Make an uninitialized vector for SIZE objects. NOTE: you must |
| @@ -3926,7 +3925,11 @@ extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t); | |||
| 3926 | v = make_uninit_vector (3); | 3925 | v = make_uninit_vector (3); |
| 3927 | ASET (v, 0, obj0); | 3926 | ASET (v, 0, obj0); |
| 3928 | ASET (v, 1, Ffunction_can_gc ()); | 3927 | ASET (v, 1, Ffunction_can_gc ()); |
| 3929 | ASET (v, 2, obj1); */ | 3928 | ASET (v, 2, obj1); |
| 3929 | |||
| 3930 | allocate_vector has a similar problem. */ | ||
| 3931 | |||
| 3932 | extern struct Lisp_Vector *allocate_vector (ptrdiff_t); | ||
| 3930 | 3933 | ||
| 3931 | INLINE Lisp_Object | 3934 | INLINE Lisp_Object |
| 3932 | make_uninit_vector (ptrdiff_t size) | 3935 | make_uninit_vector (ptrdiff_t size) |
diff --git a/src/nsselect.m b/src/nsselect.m index 38ac66e9c7b..7b1937f5d99 100644 --- a/src/nsselect.m +++ b/src/nsselect.m | |||
| @@ -114,7 +114,7 @@ clean_local_selection_data (Lisp_Object obj) | |||
| 114 | 114 | ||
| 115 | if (size == 1) | 115 | if (size == 1) |
| 116 | return clean_local_selection_data (AREF (obj, 0)); | 116 | return clean_local_selection_data (AREF (obj, 0)); |
| 117 | copy = make_uninit_vector (size); | 117 | copy = make_nil_vector (size); |
| 118 | for (i = 0; i < size; i++) | 118 | for (i = 0; i < size; i++) |
| 119 | ASET (copy, i, clean_local_selection_data (AREF (obj, i))); | 119 | ASET (copy, i, clean_local_selection_data (AREF (obj, i))); |
| 120 | return copy; | 120 | return copy; |
diff --git a/src/nsxwidget.m b/src/nsxwidget.m index 370abee395c..e81ca7fc0cb 100644 --- a/src/nsxwidget.m +++ b/src/nsxwidget.m | |||
| @@ -388,7 +388,7 @@ js_to_lisp (id value) | |||
| 388 | NSArray *nsarr = (NSArray *) value; | 388 | NSArray *nsarr = (NSArray *) value; |
| 389 | EMACS_INT n = nsarr.count; | 389 | EMACS_INT n = nsarr.count; |
| 390 | Lisp_Object obj; | 390 | Lisp_Object obj; |
| 391 | struct Lisp_Vector *p = allocate_vector (n); | 391 | struct Lisp_Vector *p = allocate_nil_vector (n); |
| 392 | 392 | ||
| 393 | for (ptrdiff_t i = 0; i < n; ++i) | 393 | for (ptrdiff_t i = 0; i < n; ++i) |
| 394 | p->contents[i] = js_to_lisp ([nsarr objectAtIndex:i]); | 394 | p->contents[i] = js_to_lisp ([nsarr objectAtIndex:i]); |
| @@ -401,7 +401,7 @@ js_to_lisp (id value) | |||
| 401 | NSArray *keys = nsdict.allKeys; | 401 | NSArray *keys = nsdict.allKeys; |
| 402 | ptrdiff_t n = keys.count; | 402 | ptrdiff_t n = keys.count; |
| 403 | Lisp_Object obj; | 403 | Lisp_Object obj; |
| 404 | struct Lisp_Vector *p = allocate_vector (n); | 404 | struct Lisp_Vector *p = allocate_nil_vector (n); |
| 405 | 405 | ||
| 406 | for (ptrdiff_t i = 0; i < n; ++i) | 406 | for (ptrdiff_t i = 0; i < n; ++i) |
| 407 | { | 407 | { |
diff --git a/src/search.c b/src/search.c index 38c64caf7c0..23b31d92810 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -3271,7 +3271,7 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */) | |||
| 3271 | TYPE_MAXIMUM (ptrdiff_t), &nl_count_cache, NULL, true); | 3271 | TYPE_MAXIMUM (ptrdiff_t), &nl_count_cache, NULL, true); |
| 3272 | 3272 | ||
| 3273 | /* Create vector and populate it. */ | 3273 | /* Create vector and populate it. */ |
| 3274 | cache_newlines = make_uninit_vector (nl_count_cache); | 3274 | cache_newlines = make_vector (nl_count_cache, make_fixnum (-1)); |
| 3275 | 3275 | ||
| 3276 | if (nl_count_cache) | 3276 | if (nl_count_cache) |
| 3277 | { | 3277 | { |
| @@ -3285,15 +3285,12 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */) | |||
| 3285 | break; | 3285 | break; |
| 3286 | ASET (cache_newlines, i, make_fixnum (found - 1)); | 3286 | ASET (cache_newlines, i, make_fixnum (found - 1)); |
| 3287 | } | 3287 | } |
| 3288 | /* Fill the rest of slots with an invalid position. */ | ||
| 3289 | for ( ; i < nl_count_cache; i++) | ||
| 3290 | ASET (cache_newlines, i, make_fixnum (-1)); | ||
| 3291 | } | 3288 | } |
| 3292 | 3289 | ||
| 3293 | /* Now do the same, but without using the cache. */ | 3290 | /* Now do the same, but without using the cache. */ |
| 3294 | find_newline1 (BEGV, BEGV_BYTE, ZV, ZV_BYTE, | 3291 | find_newline1 (BEGV, BEGV_BYTE, ZV, ZV_BYTE, |
| 3295 | TYPE_MAXIMUM (ptrdiff_t), &nl_count_buf, NULL, true); | 3292 | TYPE_MAXIMUM (ptrdiff_t), &nl_count_buf, NULL, true); |
| 3296 | buf_newlines = make_uninit_vector (nl_count_buf); | 3293 | buf_newlines = make_vector (nl_count_buf, make_fixnum (-1)); |
| 3297 | if (nl_count_buf) | 3294 | if (nl_count_buf) |
| 3298 | { | 3295 | { |
| 3299 | for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++) | 3296 | for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++) |
| @@ -3306,8 +3303,6 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */) | |||
| 3306 | break; | 3303 | break; |
| 3307 | ASET (buf_newlines, i, make_fixnum (found - 1)); | 3304 | ASET (buf_newlines, i, make_fixnum (found - 1)); |
| 3308 | } | 3305 | } |
| 3309 | for ( ; i < nl_count_buf; i++) | ||
| 3310 | ASET (buf_newlines, i, make_fixnum (-1)); | ||
| 3311 | } | 3306 | } |
| 3312 | 3307 | ||
| 3313 | /* Construct the value and return it. */ | 3308 | /* Construct the value and return it. */ |
diff --git a/src/syntax.c b/src/syntax.c index a03202d386c..9f77ea5f9b0 100644 --- a/src/syntax.c +++ b/src/syntax.c | |||
| @@ -3617,9 +3617,9 @@ init_syntax_once (void) | |||
| 3617 | DEFSYM (Qsyntax_table, "syntax-table"); | 3617 | DEFSYM (Qsyntax_table, "syntax-table"); |
| 3618 | 3618 | ||
| 3619 | /* Create objects which can be shared among syntax tables. */ | 3619 | /* Create objects which can be shared among syntax tables. */ |
| 3620 | Vsyntax_code_object = make_uninit_vector (Smax); | 3620 | Vsyntax_code_object = make_nil_vector (Smax); |
| 3621 | for (i = 0; i < Smax; i++) | 3621 | for (i = 0; i < Smax; i++) |
| 3622 | ASET (Vsyntax_code_object, i, Fcons (make_fixnum (i), Qnil)); | 3622 | ASET (Vsyntax_code_object, i, list1 (make_fixnum (i))); |
| 3623 | 3623 | ||
| 3624 | /* Now we are ready to set up this property, so we can | 3624 | /* Now we are ready to set up this property, so we can |
| 3625 | create syntax tables. */ | 3625 | create syntax tables. */ |
diff --git a/src/window.c b/src/window.c index e2dea8b70ef..ef58f43a0bd 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -7465,7 +7465,7 @@ saved by this function. */) | |||
| 7465 | data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil; | 7465 | data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil; |
| 7466 | data->root_window = FRAME_ROOT_WINDOW (f); | 7466 | data->root_window = FRAME_ROOT_WINDOW (f); |
| 7467 | data->focus_frame = FRAME_FOCUS_FRAME (f); | 7467 | data->focus_frame = FRAME_FOCUS_FRAME (f); |
| 7468 | Lisp_Object tem = make_uninit_vector (n_windows); | 7468 | Lisp_Object tem = make_nil_vector (n_windows); |
| 7469 | data->saved_windows = tem; | 7469 | data->saved_windows = tem; |
| 7470 | for (ptrdiff_t i = 0; i < n_windows; i++) | 7470 | for (ptrdiff_t i = 0; i < n_windows; i++) |
| 7471 | ASET (tem, i, make_nil_vector (VECSIZE (struct saved_window))); | 7471 | ASET (tem, i, make_nil_vector (VECSIZE (struct saved_window))); |
diff --git a/src/xselect.c b/src/xselect.c index 48d6215a7bb..bf50c598b2a 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -1594,7 +1594,7 @@ selection_data_to_lisp_data (struct x_display_info *dpyinfo, | |||
| 1594 | return x_atom_to_symbol (dpyinfo, (Atom) idata[0]); | 1594 | return x_atom_to_symbol (dpyinfo, (Atom) idata[0]); |
| 1595 | else | 1595 | else |
| 1596 | { | 1596 | { |
| 1597 | Lisp_Object v = make_uninit_vector (size / sizeof (int)); | 1597 | Lisp_Object v = make_nil_vector (size / sizeof (int)); |
| 1598 | 1598 | ||
| 1599 | for (i = 0; i < size / sizeof (int); i++) | 1599 | for (i = 0; i < size / sizeof (int); i++) |
| 1600 | ASET (v, i, x_atom_to_symbol (dpyinfo, (Atom) idata[i])); | 1600 | ASET (v, i, x_atom_to_symbol (dpyinfo, (Atom) idata[i])); |
| @@ -1653,7 +1653,7 @@ selection_data_to_lisp_data (struct x_display_info *dpyinfo, | |||
| 1653 | else | 1653 | else |
| 1654 | { | 1654 | { |
| 1655 | ptrdiff_t i; | 1655 | ptrdiff_t i; |
| 1656 | Lisp_Object v = make_uninit_vector (size / X_LONG_SIZE); | 1656 | Lisp_Object v = make_nil_vector (size / X_LONG_SIZE); |
| 1657 | 1657 | ||
| 1658 | if (type == XA_INTEGER) | 1658 | if (type == XA_INTEGER) |
| 1659 | { | 1659 | { |
| @@ -1860,7 +1860,7 @@ clean_local_selection_data (Lisp_Object obj) | |||
| 1860 | Lisp_Object copy; | 1860 | Lisp_Object copy; |
| 1861 | if (size == 1) | 1861 | if (size == 1) |
| 1862 | return clean_local_selection_data (AREF (obj, 0)); | 1862 | return clean_local_selection_data (AREF (obj, 0)); |
| 1863 | copy = make_uninit_vector (size); | 1863 | copy = make_nil_vector (size); |
| 1864 | for (i = 0; i < size; i++) | 1864 | for (i = 0; i < size; i++) |
| 1865 | ASET (copy, i, clean_local_selection_data (AREF (obj, i))); | 1865 | ASET (copy, i, clean_local_selection_data (AREF (obj, i))); |
| 1866 | return copy; | 1866 | return copy; |
diff --git a/src/xwidget.c b/src/xwidget.c index c61f5bef88d..154b3e9c82c 100644 --- a/src/xwidget.c +++ b/src/xwidget.c | |||
| @@ -343,7 +343,7 @@ webkit_js_to_lisp (JSCValue *value) | |||
| 343 | memory_full (SIZE_MAX); | 343 | memory_full (SIZE_MAX); |
| 344 | 344 | ||
| 345 | ptrdiff_t n = dlen; | 345 | ptrdiff_t n = dlen; |
| 346 | struct Lisp_Vector *p = allocate_vector (n); | 346 | struct Lisp_Vector *p = allocate_nil_vector (n); |
| 347 | 347 | ||
| 348 | for (ptrdiff_t i = 0; i < n; ++i) | 348 | for (ptrdiff_t i = 0; i < n; ++i) |
| 349 | { | 349 | { |
| @@ -361,7 +361,7 @@ webkit_js_to_lisp (JSCValue *value) | |||
| 361 | Lisp_Object obj; | 361 | Lisp_Object obj; |
| 362 | if (PTRDIFF_MAX < n) | 362 | if (PTRDIFF_MAX < n) |
| 363 | memory_full (n); | 363 | memory_full (n); |
| 364 | struct Lisp_Vector *p = allocate_vector (n); | 364 | struct Lisp_Vector *p = allocate_nil_vector (n); |
| 365 | 365 | ||
| 366 | for (ptrdiff_t i = 0; i < n; ++i) | 366 | for (ptrdiff_t i = 0; i < n; ++i) |
| 367 | { | 367 | { |