diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-03-31 07:35:02 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-03-31 07:35:02 -0700 |
commit | 7dd07115e27953fb5ab8a7bf9fb5602a52b0ef68 (patch) | |
tree | e7833aed7bb2e6458d2fbf30d337804d5c25787d | |
parent | 5fbacce2db6e38384adb650ce32af7c2dcbcbe95 (diff) | |
download | txr-7dd07115e27953fb5ab8a7bf9fb5602a52b0ef68.tar.gz txr-7dd07115e27953fb5ab8a7bf9fb5602a52b0ef68.tar.bz2 txr-7dd07115e27953fb5ab8a7bf9fb5602a52b0ef68.zip |
Array overrun fix in apply.
* eval.c (APPLY_ARGS): New preprocessor symbol, replaces
hard-coded 32 inside apply.
(apply): Use APPLY_ARGS for argument array.
Fix overrun of args array in non-variadic function case when
list has more than APPLY_ARGS elements.
Eliminate superflous "variadic" local variable.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | eval.c | 23 |
2 files changed, 22 insertions, 12 deletions
@@ -1,5 +1,16 @@ 2015-03-31 Kaz Kylheku <kaz@kylheku.com> + Array overrun fix in apply. + + * eval.c (APPLY_ARGS): New preprocessor symbol, replaces + hard-coded 32 inside apply. + (apply): Use APPLY_ARGS for argument array. + Fix overrun of args array in non-variadic function case when + list has more than APPLY_ARGS elements. + Eliminate superflous "variadic" local variable. + +2015-03-31 Kaz Kylheku <kaz@kylheku.com> + Deal with spurious retention in function application. * gc.h (zap): New inline function. @@ -50,6 +50,8 @@ #include "combi.h" #include "eval.h" +#define APPLY_ARGS 32 + typedef val (*opfun_t)(val, val); typedef val (*mefun_t)(val, val); @@ -607,8 +609,8 @@ static val get_param_syms(val params) val apply(val fun, val arglist, val ctx_form) { - val arg[32], *p = arg; - int variadic, fixparam, reqargs, nargs; + val arg[APPLY_ARGS], *p = arg; + int fixparam, reqargs, nargs; val ctx = if3(ctx_form, car(ctx_form), apply_s); if (fun && symbolp(fun)) { @@ -620,7 +622,7 @@ val apply(val fun, val arglist, val ctx_form) if (!functionp(fun)) { for (nargs = 0; - (p < arg + 32) && consp(arglist); + (p < arg + APPLY_ARGS) && consp(arglist); nargs++, p++, arglist = cdr(arglist)) { *p = car(arglist); @@ -638,22 +640,19 @@ val apply(val fun, val arglist, val ctx_form) arglist = arglist_conv; } - variadic = fun->f.variadic; fixparam = fun->f.fixparam; reqargs = fixparam - fun->f.optargs; - if (!variadic) { - for (; arglist; arglist = cdr(arglist)) + if (!fun->f.variadic) { + for (; arglist && p < arg + APPLY_ARGS; arglist = cdr(arglist)) *p++ = car(arglist); - nargs = p - arg; - - if (nargs < reqargs) - eval_error(ctx_form, lit("~s: missing required arguments"), + if (arglist) + eval_error(ctx_form, lit("~s: too many arguments"), ctx, nao); - if (nargs > fixparam) - eval_error(ctx_form, lit("~s: too many arguments"), + if ((nargs = p - arg) < reqargs) + eval_error(ctx_form, lit("~s: missing required arguments"), ctx, nao); for (; nargs < fixparam; nargs++) |