diff --git a/src/code.c b/src/code.c index 8e8ddb6794..1b5a237fe7 100644 --- a/src/code.c +++ b/src/code.c @@ -259,6 +259,10 @@ Stat NewStatOrExpr(CodeState * cs, UInt type, UInt size, UInt line) StatHeader * header = STAT_HEADER(cs, stat); header->line = line; header->size = size; + // check size fits inside header + if (header->size != size) { + ErrorQuit("function too large for parser", 0, 0); + } header->type = type; RegisterStatWithHook(GET_GAPNAMEID_BODY(cs->currBody), line, type); // return the new statement diff --git a/tst/testinstall/function.tst b/tst/testinstall/function.tst index 039f57dd6e..19b3379ce1 100644 --- a/tst/testinstall/function.tst +++ b/tst/testinstall/function.tst @@ -339,5 +339,30 @@ function ( x ) return ([ [ x ] ]{[ 1 ]}{[ 1 ]})[1, 1]; end gap> funcloop(x -> ([ [ x ] ]{[ 1 ]}{[ 1 ]}){[ 1 ]}); # EXPR_ELMS_LIST function ( x ) return ([ [ x ] ]{[ 1 ]}{[ 1 ]}){[ 1 ]}; end +# Test functions with very large lists +gap> r := List([1..(16777216/GAPInfo.BytesPerVariable)-1]);; +gap> funcstr := String(r);; +gap> funcstr := Concatenation("func := function() return ", funcstr, "; end;");; +gap> Read(InputTextString(funcstr));; +gap> func() = r; +true +gap> funcstr := String(List([1..(16777216/GAPInfo.BytesPerVariable)], x -> x));; +gap> funcstr := Concatenation("func := function() return ", funcstr, "; end;");; +gap> Read(InputTextString(funcstr));; +Error, function too large for parser + +# Test functions with very large records +gap> r := rec();; for x in [1..(16777216/GAPInfo.BytesPerVariable-2)/2] do r.(x) := x; od;; +gap> funcstr := String(r);; +gap> funcstr := Concatenation("func := function() return ", funcstr, "; end;");; +gap> Read(InputTextString(funcstr));; +gap> func() = r; +true +gap> r := rec();; for x in [1..(16777216/GAPInfo.BytesPerVariable)/2] do r.(x) := x; od;; +gap> funcstr := String(r);; +gap> funcstr := Concatenation("func := function() return ", funcstr, "; end;");; +gap> Read(InputTextString(funcstr));; +Error, function too large for parser + # gap> STOP_TEST("function.tst", 1); diff --git a/tst/testinstall/recordname.tst b/tst/testinstall/recordname.tst index cd4cf8be4f..e9044e812b 100644 --- a/tst/testinstall/recordname.tst +++ b/tst/testinstall/recordname.tst @@ -92,8 +92,8 @@ sitive integer) gap> \.(r, "a"); Error, Record Element: must be a positive small integer (not a list (st\ ring)) -gap> \.(r, 1000000); -Error, Record Element: must be a valid rnam (not the integer 1000000) +gap> \.(r, 100000000); +Error, Record Element: must be a valid rnam (not the integer 100000000) ## gap> IsBound\.(r, RNamObj("y")); @@ -112,8 +112,8 @@ sitive integer) gap> IsBound\.(r, "a"); Error, Record IsBound: must be a positive small integer (not a list (st\ ring)) -gap> IsBound\.(r, 1000000); -Error, Record IsBound: must be a valid rnam (not the integer 1000000) +gap> IsBound\.(r, 100000000); +Error, Record IsBound: must be a valid rnam (not the integer 100000000) ## gap> r; @@ -137,8 +137,8 @@ itive integer) gap> Unbind\.(r, "a"); Error, Record Unbind: must be a positive small integer (not a list (str\ ing)) -gap> Unbind\.(r, 1000000); -Error, Record Unbind: must be a valid rnam (not the integer 1000000) +gap> Unbind\.(r, 100000000); +Error, Record Unbind: must be a valid rnam (not the integer 100000000) ## gap> r; @@ -164,7 +164,7 @@ Error, Record Assignment: must be a positive small integer (not a large\ gap> \.\:\=(r, "a", 1); Error, Record Assignment: must be a positive small integer (not a list \ (string)) -gap> \.\:\=(r, 1000000, 1); +gap> \.\:\=(r, 100000000, 1); Error, Record Assignment: must be a valid rnam (not the integer 1000000\ -) +00) gap> STOP_TEST( "recordname.tst", 1);