diff options
| author | Eli Zaretskii | 2019-06-20 21:07:37 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2019-06-20 21:07:37 +0300 |
| commit | e4e171bcac366f4d8538082230c804ae12cb2059 (patch) | |
| tree | ce904ae9ab2ed89f5e2c366ef5b9606bd51631a6 | |
| parent | afc9d9b3ad9ea00e7255a697bd3d0e297554edbe (diff) | |
| download | emacs-e4e171bcac366f4d8538082230c804ae12cb2059.tar.gz emacs-e4e171bcac366f4d8538082230c804ae12cb2059.zip | |
Fix aborts when the value of a display property causes redisplay
* src/xdisp.c (handle_single_display_spec): Protect the bidi
cache from evaluation that triggers redisplay. (Bug#36312)
| -rw-r--r-- | src/xdisp.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 945174e09c5..5d70440f1cb 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -5000,6 +5000,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 5000 | Lisp_Object form; | 5000 | Lisp_Object form; |
| 5001 | Lisp_Object location, value; | 5001 | Lisp_Object location, value; |
| 5002 | struct text_pos start_pos = *position; | 5002 | struct text_pos start_pos = *position; |
| 5003 | void *itdata = NULL; | ||
| 5003 | 5004 | ||
| 5004 | /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. | 5005 | /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM. |
| 5005 | If the result is non-nil, use VALUE instead of SPEC. */ | 5006 | If the result is non-nil, use VALUE instead of SPEC. */ |
| @@ -5029,7 +5030,11 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 5029 | specbind (Qobject, object); | 5030 | specbind (Qobject, object); |
| 5030 | specbind (Qposition, make_fixnum (CHARPOS (*position))); | 5031 | specbind (Qposition, make_fixnum (CHARPOS (*position))); |
| 5031 | specbind (Qbuffer_position, make_fixnum (bufpos)); | 5032 | specbind (Qbuffer_position, make_fixnum (bufpos)); |
| 5033 | /* Save and restore the bidi cache, since FORM could be crazy | ||
| 5034 | enough to re-enter redisplay, e.g., by calling 'message'. */ | ||
| 5035 | itdata = bidi_shelve_cache (); | ||
| 5032 | form = safe_eval (form); | 5036 | form = safe_eval (form); |
| 5037 | bidi_unshelve_cache (itdata, false); | ||
| 5033 | form = unbind_to (count, form); | 5038 | form = unbind_to (count, form); |
| 5034 | } | 5039 | } |
| 5035 | 5040 | ||
| @@ -5069,8 +5074,10 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 5069 | Value is the new height. */ | 5074 | Value is the new height. */ |
| 5070 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | 5075 | struct face *face = FACE_FROM_ID (it->f, it->face_id); |
| 5071 | Lisp_Object height; | 5076 | Lisp_Object height; |
| 5077 | itdata = bidi_shelve_cache (); | ||
| 5072 | height = safe_call1 (it->font_height, | 5078 | height = safe_call1 (it->font_height, |
| 5073 | face->lface[LFACE_HEIGHT_INDEX]); | 5079 | face->lface[LFACE_HEIGHT_INDEX]); |
| 5080 | bidi_unshelve_cache (itdata, false); | ||
| 5074 | if (NUMBERP (height)) | 5081 | if (NUMBERP (height)) |
| 5075 | new_height = XFLOATINT (height); | 5082 | new_height = XFLOATINT (height); |
| 5076 | } | 5083 | } |
| @@ -5092,7 +5099,9 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 5092 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | 5099 | struct face *face = FACE_FROM_ID (it->f, it->face_id); |
| 5093 | 5100 | ||
| 5094 | specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); | 5101 | specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); |
| 5102 | itdata = bidi_shelve_cache (); | ||
| 5095 | value = safe_eval (it->font_height); | 5103 | value = safe_eval (it->font_height); |
| 5104 | bidi_unshelve_cache (itdata, false); | ||
| 5096 | value = unbind_to (count, value); | 5105 | value = unbind_to (count, value); |
| 5097 | 5106 | ||
| 5098 | if (NUMBERP (value)) | 5107 | if (NUMBERP (value)) |