diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-10-17 07:54:24 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-10-17 07:54:24 -0700 |
commit | e61bfc41ed9d522b8f679e758fe79f20b326b76b (patch) | |
tree | 187f81f89351609fb940056b858d8424c0e35ad9 /lib.c | |
parent | 24f59dc6fd38aeba9a10099c8b7a1243b18392a3 (diff) | |
download | txr-e61bfc41ed9d522b8f679e758fe79f20b326b76b.tar.gz txr-e61bfc41ed9d522b8f679e758fe79f20b326b76b.tar.bz2 txr-e61bfc41ed9d522b8f679e758fe79f20b326b76b.zip |
vm: prevent overflow of fixparam field in function.
Functions can only have 127 fixed parameters; some code
ignores this when assigning to the bitfield.
* lib.h (FIXPARAM_BITS, FIXPARAM_MAX): New preprocessor
symbols.
(struct func): Use FIXPARAM_BITS for defining fixparam and
optargs bitfields instead of hard-coded 7.
* lib.c (func_vm): Sanity check the fixparam and reqags
parameters: 0 <= reqargs <= fixparam <= FIXPARAM_MAX.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 26 |
1 files changed, 17 insertions, 9 deletions
@@ -6128,15 +6128,23 @@ val func_interp(val env, val form) val func_vm(val closure, val desc, int fixparam, int reqargs, int variadic) { - val obj = make_obj(); - obj->f.type = FUN; - obj->f.functype = FVM; - obj->f.env = closure; - obj->f.f.vm_desc = desc; - obj->f.fixparam = fixparam; - obj->f.optargs = fixparam - reqargs; - obj->f.variadic = (variadic != 0); - return obj; + if (fixparam > FIXPARAM_MAX) { + uw_throwf(error_s, lit("closure in ~s with more than ~s fixed parameters"), + desc, unum(FIXPARAM_MAX), nao); + } else if (fixparam < 0 || reqargs < 0 || reqargs > fixparam) { + uw_throwf(error_s, lit("closure in ~s with bogus parameters"), + desc, nao); + } else { + val obj = make_obj(); + obj->f.type = FUN; + obj->f.functype = FVM; + obj->f.env = closure; + obj->f.f.vm_desc = desc; + obj->f.fixparam = fixparam; + obj->f.optargs = fixparam - reqargs; + obj->f.variadic = (variadic != 0); + return obj; + } } val copy_fun(val ofun) |