aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Stephani2016-11-09 23:13:52 +0100
committerPhilipp Stephani2016-11-18 18:02:57 +0100
commit0d913da15c094bf596dd685acecf3438228c15cf (patch)
tree342d5e0222a35dc93cca8858317e038a76e91c27 /src
parent49ac78022802dfff08367477e8d09d17d3c73e68 (diff)
downloademacs-0d913da15c094bf596dd685acecf3438228c15cf.tar.gz
emacs-0d913da15c094bf596dd685acecf3438228c15cf.zip
Prevent dubious argument lists
See Bug#24912 and Bug#24913. * src/eval.c (funcall_lambda): Detect more dubious argument lists. * lisp/emacs-lisp/bytecomp.el (byte-compile-check-lambda-list): Detect more dubious argument lists. * test/src/eval-tests.el (eval-tests--bugs-24912-and-24913): Add unit test.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c
index caeb791c19b..884e1ebfb89 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2888,6 +2888,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
2888 emacs_abort (); 2888 emacs_abort ();
2889 2889
2890 i = optional = rest = 0; 2890 i = optional = rest = 0;
2891 bool previous_optional_or_rest = false;
2891 for (; CONSP (syms_left); syms_left = XCDR (syms_left)) 2892 for (; CONSP (syms_left); syms_left = XCDR (syms_left))
2892 { 2893 {
2893 QUIT; 2894 QUIT;
@@ -2897,9 +2898,19 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
2897 xsignal1 (Qinvalid_function, fun); 2898 xsignal1 (Qinvalid_function, fun);
2898 2899
2899 if (EQ (next, Qand_rest)) 2900 if (EQ (next, Qand_rest))
2900 rest = 1; 2901 {
2902 if (rest || previous_optional_or_rest)
2903 xsignal1 (Qinvalid_function, fun);
2904 rest = 1;
2905 previous_optional_or_rest = true;
2906 }
2901 else if (EQ (next, Qand_optional)) 2907 else if (EQ (next, Qand_optional))
2902 optional = 1; 2908 {
2909 if (optional || rest || previous_optional_or_rest)
2910 xsignal1 (Qinvalid_function, fun);
2911 optional = 1;
2912 previous_optional_or_rest = true;
2913 }
2903 else 2914 else
2904 { 2915 {
2905 Lisp_Object arg; 2916 Lisp_Object arg;
@@ -2922,10 +2933,11 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
2922 else 2933 else
2923 /* Dynamically bind NEXT. */ 2934 /* Dynamically bind NEXT. */
2924 specbind (next, arg); 2935 specbind (next, arg);
2936 previous_optional_or_rest = false;
2925 } 2937 }
2926 } 2938 }
2927 2939
2928 if (!NILP (syms_left)) 2940 if (!NILP (syms_left) || previous_optional_or_rest)
2929 xsignal1 (Qinvalid_function, fun); 2941 xsignal1 (Qinvalid_function, fun);
2930 else if (i < nargs) 2942 else if (i < nargs)
2931 xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs)); 2943 xsignal2 (Qwrong_number_of_arguments, fun, make_number (nargs));