diff options
| author | Eli Zaretskii | 2017-09-16 12:45:24 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2017-09-16 12:45:24 +0300 |
| commit | a103dbe36022cd2454eaeed96def1c777c049762 (patch) | |
| tree | a3455f3e0ef50b9bbc1085c3199b4434851ebf35 /src | |
| parent | 6d6dc246f93486fc8370399b6e1af8a17f371e4f (diff) | |
| download | emacs-a103dbe36022cd2454eaeed96def1c777c049762.tar.gz emacs-a103dbe36022cd2454eaeed96def1c777c049762.zip | |
Disable execution of unsafe Lisp by Enriched Text mode
* src/xdisp.c (handle_display_spec): If the display property is
wrapped in 'disable-eval' form, disable Lisp evaluation while
processing this property.
(handle_single_display_spec): Accept new argument ENABLE_EVAL_P.
If that argument is false, don't evaluate Lisp while processing
display properties.
* lisp/textmodes/enriched.el
(enriched-allow-eval-in-display-props): New defcustom.
(enriched-decode-display-prop): If
enriched-allow-eval-in-display-props is nil, wrap the display
property with 'disable-eval' to disable Lisp evaluation when the
display property is processed for display. (Bug#28350)
* lisp/gnus/mm-view.el (mm-inline-text): Re-enable processing of
enriched text.
* doc/lispref/display.texi (Display Property): Document the
'disable-eval' wrapping of 'display' properties.
* doc/emacs/text.texi (Enriched Properties): Document
'enriched-allow-eval-in-display-props'.
* etc/NEWS: Describe the security issues with Enriched Text mode
and their solution.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 8ca9037a00d..dc5dbb05762 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -876,9 +876,9 @@ static int face_before_or_after_it_pos (struct it *, bool); | |||
| 876 | static ptrdiff_t next_overlay_change (ptrdiff_t); | 876 | static ptrdiff_t next_overlay_change (ptrdiff_t); |
| 877 | static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, | 877 | static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, |
| 878 | Lisp_Object, struct text_pos *, ptrdiff_t, bool); | 878 | Lisp_Object, struct text_pos *, ptrdiff_t, bool); |
| 879 | static int handle_single_display_spec (struct it *, Lisp_Object, | 879 | static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object, |
| 880 | Lisp_Object, Lisp_Object, | 880 | Lisp_Object, struct text_pos *, |
| 881 | struct text_pos *, ptrdiff_t, int, bool); | 881 | ptrdiff_t, int, bool, bool); |
| 882 | static int underlying_face_id (struct it *); | 882 | static int underlying_face_id (struct it *); |
| 883 | 883 | ||
| 884 | #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true) | 884 | #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true) |
| @@ -4748,6 +4748,14 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4748 | ptrdiff_t bufpos, bool frame_window_p) | 4748 | ptrdiff_t bufpos, bool frame_window_p) |
| 4749 | { | 4749 | { |
| 4750 | int replacing = 0; | 4750 | int replacing = 0; |
| 4751 | bool enable_eval = true; | ||
| 4752 | |||
| 4753 | /* Support (disable-eval PROP) which is used by enriched.el. */ | ||
| 4754 | if (CONSP (spec) && EQ (XCAR (spec), Qdisable_eval)) | ||
| 4755 | { | ||
| 4756 | enable_eval = false; | ||
| 4757 | spec = XCAR (XCDR (spec)); | ||
| 4758 | } | ||
| 4751 | 4759 | ||
| 4752 | if (CONSP (spec) | 4760 | if (CONSP (spec) |
| 4753 | /* Simple specifications. */ | 4761 | /* Simple specifications. */ |
| @@ -4771,7 +4779,8 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4771 | { | 4779 | { |
| 4772 | int rv = handle_single_display_spec (it, XCAR (spec), object, | 4780 | int rv = handle_single_display_spec (it, XCAR (spec), object, |
| 4773 | overlay, position, bufpos, | 4781 | overlay, position, bufpos, |
| 4774 | replacing, frame_window_p); | 4782 | replacing, frame_window_p, |
| 4783 | enable_eval); | ||
| 4775 | if (rv != 0) | 4784 | if (rv != 0) |
| 4776 | { | 4785 | { |
| 4777 | replacing = rv; | 4786 | replacing = rv; |
| @@ -4789,7 +4798,8 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4789 | { | 4798 | { |
| 4790 | int rv = handle_single_display_spec (it, AREF (spec, i), object, | 4799 | int rv = handle_single_display_spec (it, AREF (spec, i), object, |
| 4791 | overlay, position, bufpos, | 4800 | overlay, position, bufpos, |
| 4792 | replacing, frame_window_p); | 4801 | replacing, frame_window_p, |
| 4802 | enable_eval); | ||
| 4793 | if (rv != 0) | 4803 | if (rv != 0) |
| 4794 | { | 4804 | { |
| 4795 | replacing = rv; | 4805 | replacing = rv; |
| @@ -4802,7 +4812,8 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4802 | } | 4812 | } |
| 4803 | else | 4813 | else |
| 4804 | replacing = handle_single_display_spec (it, spec, object, overlay, position, | 4814 | replacing = handle_single_display_spec (it, spec, object, overlay, position, |
| 4805 | bufpos, 0, frame_window_p); | 4815 | bufpos, 0, frame_window_p, |
| 4816 | enable_eval); | ||
| 4806 | return replacing; | 4817 | return replacing; |
| 4807 | } | 4818 | } |
| 4808 | 4819 | ||
| @@ -4847,6 +4858,8 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos) | |||
| 4847 | don't set up IT. In that case, FRAME_WINDOW_P means SPEC | 4858 | don't set up IT. In that case, FRAME_WINDOW_P means SPEC |
| 4848 | is intended to be displayed in a window on a GUI frame. | 4859 | is intended to be displayed in a window on a GUI frame. |
| 4849 | 4860 | ||
| 4861 | Enable evaluation of Lisp forms only if ENABLE_EVAL_P is true. | ||
| 4862 | |||
| 4850 | Value is non-zero if something was found which replaces the display | 4863 | Value is non-zero if something was found which replaces the display |
| 4851 | of buffer or string text. */ | 4864 | of buffer or string text. */ |
| 4852 | 4865 | ||
| @@ -4854,7 +4867,7 @@ static int | |||
| 4854 | handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | 4867 | handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, |
| 4855 | Lisp_Object overlay, struct text_pos *position, | 4868 | Lisp_Object overlay, struct text_pos *position, |
| 4856 | ptrdiff_t bufpos, int display_replaced, | 4869 | ptrdiff_t bufpos, int display_replaced, |
| 4857 | bool frame_window_p) | 4870 | bool frame_window_p, bool enable_eval_p) |
| 4858 | { | 4871 | { |
| 4859 | Lisp_Object form; | 4872 | Lisp_Object form; |
| 4860 | Lisp_Object location, value; | 4873 | Lisp_Object location, value; |
| @@ -4872,6 +4885,8 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4872 | spec = XCDR (spec); | 4885 | spec = XCDR (spec); |
| 4873 | } | 4886 | } |
| 4874 | 4887 | ||
| 4888 | if (!NILP (form) && !EQ (form, Qt) && !enable_eval_p) | ||
| 4889 | form = Qnil; | ||
| 4875 | if (!NILP (form) && !EQ (form, Qt)) | 4890 | if (!NILP (form) && !EQ (form, Qt)) |
| 4876 | { | 4891 | { |
| 4877 | ptrdiff_t count = SPECPDL_INDEX (); | 4892 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -4920,7 +4935,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4920 | steps = - steps; | 4935 | steps = - steps; |
| 4921 | it->face_id = smaller_face (it->f, it->face_id, steps); | 4936 | it->face_id = smaller_face (it->f, it->face_id, steps); |
| 4922 | } | 4937 | } |
| 4923 | else if (FUNCTIONP (it->font_height)) | 4938 | else if (FUNCTIONP (it->font_height) && enable_eval_p) |
| 4924 | { | 4939 | { |
| 4925 | /* Call function with current height as argument. | 4940 | /* Call function with current height as argument. |
| 4926 | Value is the new height. */ | 4941 | Value is the new height. */ |
| @@ -4941,7 +4956,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, | |||
| 4941 | new_height = (XFLOATINT (it->font_height) | 4956 | new_height = (XFLOATINT (it->font_height) |
| 4942 | * XINT (f->lface[LFACE_HEIGHT_INDEX])); | 4957 | * XINT (f->lface[LFACE_HEIGHT_INDEX])); |
| 4943 | } | 4958 | } |
| 4944 | else | 4959 | else if (enable_eval_p) |
| 4945 | { | 4960 | { |
| 4946 | /* Evaluate IT->font_height with `height' bound to the | 4961 | /* Evaluate IT->font_height with `height' bound to the |
| 4947 | current specified height to get the new height. */ | 4962 | current specified height to get the new height. */ |
| @@ -32204,6 +32219,10 @@ They are still logged to the *Messages* buffer. */); | |||
| 32204 | DEFSYM (Qfontified, "fontified"); | 32219 | DEFSYM (Qfontified, "fontified"); |
| 32205 | DEFSYM (Qfontification_functions, "fontification-functions"); | 32220 | DEFSYM (Qfontification_functions, "fontification-functions"); |
| 32206 | 32221 | ||
| 32222 | /* Name of the symbol which disables Lisp evaluation in 'display' | ||
| 32223 | properties. This is used by enriched.el. */ | ||
| 32224 | DEFSYM (Qdisable_eval, "disable-eval"); | ||
| 32225 | |||
| 32207 | /* Name of the face used to highlight trailing whitespace. */ | 32226 | /* Name of the face used to highlight trailing whitespace. */ |
| 32208 | DEFSYM (Qtrailing_whitespace, "trailing-whitespace"); | 32227 | DEFSYM (Qtrailing_whitespace, "trailing-whitespace"); |
| 32209 | 32228 | ||