diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-03-20 21:47:05 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-03-20 21:47:05 -0700 |
commit | c6408016c51d2936c520920fca6f94a74ec34174 (patch) | |
tree | 0647160659a4e97857b2ae273329a36dfc65d15d | |
parent | 58b96d9330262d7c80f233e7aa1f4d53a5fdd431 (diff) | |
download | txr-c6408016c51d2936c520920fca6f94a74ec34174.tar.gz txr-c6408016c51d2936c520920fca6f94a74ec34174.tar.bz2 txr-c6408016c51d2936c520920fca6f94a74ec34174.zip |
vm: funcall wrappers need to check arg count.
There is the possibility that funcall1 through funcall3 will
pass the wrong number of arguments to vm_execute_closure,
which doesn't do any checks. This is only for the code paths
which don't go through generic_funcall, when the function
has no optional arguments.
* lib.c (funcall1, funcall2, funcall3, funcall4): Check
that the closure doesn't require more fixed parameters
than we're giving it in the variadic case, or that
it doesn't require a different number of fixed parameters
we're giving it in the non-variadic case.
-rw-r--r-- | lib.c | 16 |
1 files changed, 16 insertions, 0 deletions
@@ -6386,6 +6386,8 @@ val funcall1(val fun, val arg) args_add(args, arg); return funcall_interp(fun, args); case FVM: + if (fun->f.fixparam > 1) + break; args_add(args, arg); return vm_execute_closure(fun, args); case F0: @@ -6406,6 +6408,8 @@ val funcall1(val fun, val arg) case FVM: { args_decl(args, ARGS_MIN); + if (fun->f.fixparam != 1) + break; args_add(args, arg); return vm_execute_closure(fun, args); } @@ -6436,6 +6440,8 @@ val funcall2(val fun, val arg1, val arg2) args_add2(args, arg1, arg2); return funcall_interp(fun, args); case FVM: + if (fun->f.fixparam > 2) + break; args_add2(args, arg1, arg2); return vm_execute_closure(fun, args); case F0: @@ -6462,6 +6468,8 @@ val funcall2(val fun, val arg1, val arg2) case FVM: { args_decl(args, ARGS_MIN); + if (fun->f.fixparam != 2) + break; args_add2(args, arg1, arg2); return vm_execute_closure(fun, args); } @@ -6492,6 +6500,8 @@ val funcall3(val fun, val arg1, val arg2, val arg3) args_add3(args, arg1, arg2, arg3); return funcall_interp(fun, args); case FVM: + if (fun->f.fixparam > 3) + break; args_add3(args, arg1, arg2, arg3); return vm_execute_closure(fun, args); case F0: @@ -6524,6 +6534,8 @@ val funcall3(val fun, val arg1, val arg2, val arg3) case FVM: { args_decl(args, ARGS_MIN); + if (fun->f.fixparam != 3) + break; args_add3(args, arg1, arg2, arg3); return vm_execute_closure(fun, args); } @@ -6554,6 +6566,8 @@ val funcall4(val fun, val arg1, val arg2, val arg3, val arg4) args_add4(args, arg1, arg2, arg3, arg4); return funcall_interp(fun, args); case FVM: + if (fun->f.fixparam > 4) + break; args_add4(args, arg1, arg2, arg3, arg4); return vm_execute_closure(fun, args); case F0: @@ -6592,6 +6606,8 @@ val funcall4(val fun, val arg1, val arg2, val arg3, val arg4) case FVM: { args_decl(args, ARGS_MIN); + if (fun->f.fixparam != 4) + break; args_add4(args, arg1, arg2, arg3, arg4); return vm_execute_closure(fun, args); } |