Skip to content

Commit

Permalink
kernel: fix a crash and weirdness related to 'for' loops
Browse files Browse the repository at this point in the history
The reader ("parser") did not sufficiently restrict the kind of expression
permitted as index variable in `for` loops. So one could enter e.g. this:

    for x[1] in [1] do od;

The result was a nonsensical error message. Worse, one could specify a
"constant" variable, which caused a segfault; e.g.

    for IsHPCGAP in [1] do od;
  • Loading branch information
fingolfin committed Dec 29, 2019
1 parent 55ba181 commit f47b9a9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -2050,7 +2050,9 @@ static void ReadFor(ScannerState * s, TypSymbolSet follow)
Match(s, S_FOR, "for", follow);

/* <Var> */
ReadCallVarAss(s, follow, 'r');
volatile LHSRef ref = ReadVar(s, follow);
if (ref.type != R_INVALID)
EvalRef(ref, 1);

/* 'in' <Expr> */
Match(s, S_IN, "in", S_DO|S_OD|follow);
Expand Down
36 changes: 36 additions & 0 deletions tst/testinstall/coder.tst
Original file line number Diff line number Diff line change
Expand Up @@ -300,5 +300,41 @@ gap> function() Unbind(l![fail]); end();
Error, PosObj Assignment: <position> must be a positive small integer (not the\
value 'fail')

#
# weird corner cases in for loop index variables
#
gap> function() for + in [1,2,3] do od; end();
Syntax error: Identifier expected in stream:1
function() for + in [1,2,3] do od; end();
^
gap> function() local x; for x[1] in [1,2,3] do od; end();
Syntax error: in expected in stream:1
function() local x; for x[1] in [1,2,3] do od; end();
^
gap> function() local x; for x{[1]} in [1,2,3] do od; end();
Syntax error: in expected in stream:1
function() local x; for x{[1]} in [1,2,3] do od; end();
^
gap> function() for IsHPCGAP in [1,2,3] do od; end();
Error, Variable: 'IsHPCGAP' is constant
gap> function() for IsHPCGAP[1] in [1,2,3] do od; end();
Syntax error: in expected in stream:1
function() for IsHPCGAP[1] in [1,2,3] do od; end();
^
gap> function() for IsHPCGAP{[1]} in [1,2,3] do od; end();
Syntax error: in expected in stream:1
function() for IsHPCGAP{[1]} in [1,2,3] do od; end();
^
gap> function() for PrintObj in [1,2,3] do od; end();
Error, Variable: 'PrintObj' is read only
gap> function() for PrintObj[1] in [1,2,3] do od; end();
Syntax error: in expected in stream:1
function() for PrintObj[1] in [1,2,3] do od; end();
^
gap> function() for PrintObj{[1]} in [1,2,3] do od; end();
Syntax error: in expected in stream:1
function() for PrintObj{[1]} in [1,2,3] do od; end();
^

#
gap> STOP_TEST("coder.tst", 1);
36 changes: 36 additions & 0 deletions tst/testinstall/interpreter.tst
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,42 @@ gap> Unbind(l![fail]);
Error, PosObj Assignment: <position> must be a positive small integer (not the\
value 'fail')

#
# weird corner cases in for loop index variables
#
gap> for + in [1,2,3] do od;
Syntax error: Identifier expected in stream:1
for + in [1,2,3] do od;
^
gap> for x[1] in [1,2,3] do od;
Syntax error: in expected in stream:1
for x[1] in [1,2,3] do od;
^
gap> for x{[1]} in [1,2,3] do od;
Syntax error: in expected in stream:1
for x{[1]} in [1,2,3] do od;
^
gap> for IsHPCGAP in [1,2,3] do od;
Error, Variable: 'IsHPCGAP' is constant
gap> for IsHPCGAP[1] in [1,2,3] do od;
Syntax error: in expected in stream:1
for IsHPCGAP[1] in [1,2,3] do od;
^
gap> for IsHPCGAP{[1]} in [1,2,3] do od;
Syntax error: in expected in stream:1
for IsHPCGAP{[1]} in [1,2,3] do od;
^
gap> for PrintObj in [1,2,3] do od;
Error, Variable: 'PrintObj' is read only
gap> for PrintObj[1] in [1,2,3] do od;
Syntax error: in expected in stream:1
for PrintObj[1] in [1,2,3] do od;
^
gap> for PrintObj{[1]} in [1,2,3] do od;
Syntax error: in expected in stream:1
for PrintObj{[1]} in [1,2,3] do od;
^

#
#
gap> STOP_TEST("interpreter.tst", 1);

0 comments on commit f47b9a9

Please sign in to comment.