aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2017-09-16 12:45:24 +0300
committerEli Zaretskii2017-09-16 12:45:24 +0300
commita103dbe36022cd2454eaeed96def1c777c049762 (patch)
treea3455f3e0ef50b9bbc1085c3199b4434851ebf35 /src
parent6d6dc246f93486fc8370399b6e1af8a17f371e4f (diff)
downloademacs-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.c37
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);
876static ptrdiff_t next_overlay_change (ptrdiff_t); 876static ptrdiff_t next_overlay_change (ptrdiff_t);
877static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, 877static 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);
879static int handle_single_display_spec (struct it *, Lisp_Object, 879static 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);
882static int underlying_face_id (struct it *); 882static 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
4854handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, 4867handle_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