Skip to content

Commit

Permalink
Fix passing invalid rnam values to records
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson committed Jun 5, 2019
1 parent 5d81b55 commit e091884
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,19 @@ void ErrorMayQuit(const Char * msg, Int arg1, Int arg2)
Panic("ErrorMayQuit must not return");
}

/****************************************************************************
**
*F GetValidRNam( <funcname>, <rnam> ) . check if <rnam> is a valid prec rnam
*/
UInt GetValidRNam(const char * funcname, Obj rnam)
{
RequirePositiveSmallInt(funcname, rnam, "<rnam>");
UInt val = INT_INTOBJ(rnam);
RequireArgumentCondition(funcname, rnam, IS_VALID_RNAM(val),
"must be a valid rnam");
return val;
}

/****************************************************************************
**
*F CheckIsPossList( <desc>, <poss> ) . . . . . . . . . . check for poss list
Expand Down
8 changes: 8 additions & 0 deletions src/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,14 @@ GetPositiveSmallIntEx(const char * funcname, Obj op, const char * argname)
#define GetPositiveSmallInt(funcname, op) \
GetPositiveSmallIntEx(funcname, op, NICE_ARGNAME(op))

/****************************************************************************
**
*F GetValidRNam
**
** Check if <rnam> is a valid prec rnam. Error if not.
** Returns the rnam, when it is valid.
*/
UInt GetValidRNam(const char * funcname, Obj rnam);

/****************************************************************************
**
Expand Down
14 changes: 10 additions & 4 deletions src/records.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ static Obj HashRNam;

static Obj NamesRNam;

extern inline Int IS_VALID_RNAM(UInt rnam)
{
return rnam != 0 && rnam <= LEN_PLIST(NamesRNam);
}

extern inline Obj NAME_RNAM(UInt rnam)
{
return ELM_PLIST(NamesRNam, rnam);
Expand Down Expand Up @@ -334,7 +339,7 @@ static Obj ElmRecOper;

static Obj ElmRecHandler(Obj self, Obj rec, Obj rnam)
{
return ELM_REC( rec, INT_INTOBJ(rnam) );
return ELM_REC(rec, GetValidRNam("Record Element", rnam));
}

static Obj ElmRecError(Obj rec, UInt rnam)
Expand Down Expand Up @@ -368,7 +373,8 @@ static Obj IsbRecOper;

static Obj IsbRecHandler(Obj self, Obj rec, Obj rnam)
{
return (ISB_REC( rec, INT_INTOBJ(rnam) ) ? True : False);
return (ISB_REC(rec, GetValidRNam("Record IsBound", rnam)) ? True
: False);
}

static Int IsbRecError(Obj rec, UInt rnam)
Expand Down Expand Up @@ -397,7 +403,7 @@ static Obj AssRecOper;

static Obj AssRecHandler(Obj self, Obj rec, Obj rnam, Obj obj)
{
ASS_REC( rec, INT_INTOBJ(rnam), obj );
ASS_REC(rec, GetValidRNam("Record Assignment", rnam), obj);
return 0;
}

Expand Down Expand Up @@ -426,7 +432,7 @@ static Obj UnbRecOper;

static Obj UnbRecHandler(Obj self, Obj rec, Obj rnam)
{
UNB_REC( rec, INT_INTOBJ(rnam) );
UNB_REC(rec, GetValidRNam("Record Unbind", rnam));
return 0;
}

Expand Down
11 changes: 11 additions & 0 deletions src/records.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,22 @@

#include "objects.h"

/****************************************************************************
**
*F IS_VALID_RNAM(<rnam>) . . . . . . . . . . . . . check if <rnam> is valid
**
** 'IS_VALID_RNAM' returns if <rnam> is a valid record name.
*/
Int IS_VALID_RNAM(UInt rnam);

/****************************************************************************
**
*F NAME_RNAM(<rnam>) . . . . . . . . . . . name for a record name as an Obj
**
** 'NAME_RNAM' returns the name (as an Obj) for the record name <rnam>.
**
** This function should only be called for valid RNAMs (this can be checked
** with IS_VALID_RNAM).
*/
Obj NAME_RNAM(UInt rnam);

Expand Down
93 changes: 93 additions & 0 deletions tst/testinstall/recordname.tst
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,97 @@ Syntax error: Identifiers in GAP must consist of at most 1023 characters. in s\
tream:2
aaaxyz := 1; # 1024 chars
^^^^^
gap> r := rec(y := 2);
rec( y := 2 )
gap> \.(r, RNamObj("y"));
2
gap> \.(r, RNamObj("x"));
Error, Record Element: '<rec>.x' must have an assigned value
gap> \.(r, 0);
Error, Record Element: <rnam> must be a positive small integer (not the intege\
r 0)
gap> \.(r, -1);
Error, Record Element: <rnam> must be a positive small integer (not the intege\
r -1)
gap> \.(r, 2^1000);
Error, Record Element: <rnam> must be a positive small integer (not a large po\
sitive integer)
gap> \.(r, "a");
Error, Record Element: <rnam> must be a positive small integer (not a list (st\
ring))
gap> \.(r, 1000000);
Error, Record Element: <rnam> must be a valid rnam (not the integer 1000000)
##
gap> IsBound\.(r, RNamObj("y"));
true
gap> IsBound\.(r, RNamObj("x"));
false
gap> IsBound\.(r, 0);
Error, Record IsBound: <rnam> must be a positive small integer (not the intege\
r 0)
gap> IsBound\.(r, -1);
Error, Record IsBound: <rnam> must be a positive small integer (not the intege\
r -1)
gap> IsBound\.(r, 2^1000);
Error, Record IsBound: <rnam> must be a positive small integer (not a large po\
sitive integer)
gap> IsBound\.(r, "a");
Error, Record IsBound: <rnam> must be a positive small integer (not a list (st\
ring))
gap> IsBound\.(r, 1000000);
Error, Record IsBound: <rnam> must be a valid rnam (not the integer 1000000)
##
gap> r;
rec( y := 2 )
gap> Unbind\.(r, RNamObj("y"));
gap> r;
rec( )
gap> Unbind\.(r, RNamObj("y"));
gap> r;
rec( )
gap> Unbind\.(r, RNamObj("x"));
gap> Unbind\.(r, 0);
Error, Record Unbind: <rnam> must be a positive small integer (not the integer\
0)
gap> Unbind\.(r, -1);
Error, Record Unbind: <rnam> must be a positive small integer (not the integer\
-1)
gap> Unbind\.(r, 2^1000);
Error, Record Unbind: <rnam> must be a positive small integer (not a large pos\
itive integer)
gap> Unbind\.(r, "a");
Error, Record Unbind: <rnam> must be a positive small integer (not a list (str\
ing))
gap> Unbind\.(r, 1000000);
Error, Record Unbind: <rnam> must be a valid rnam (not the integer 1000000)
##
gap> r;
rec( )
gap> \.\:\=(r,RNamObj("y"), 2);
gap> r;
rec( y := 2 )
gap> \.\:\=(r,RNamObj("y"), 4);
gap> r;
rec( y := 4 )
gap> \.\:\=(r,RNamObj("x"), 5);
gap> r;
rec( x := 5, y := 4 )
gap> \.\:\=(r, 0, 1);
Error, Record Assignment: <rnam> must be a positive small integer (not the int\
eger 0)
gap> \.\:\=(r, -1, 1);
Error, Record Assignment: <rnam> must be a positive small integer (not the int\
eger -1)
gap> \.\:\=(r, 2^1000, 1);
Error, Record Assignment: <rnam> must be a positive small integer (not a large\
positive integer)
gap> \.\:\=(r, "a", 1);
Error, Record Assignment: <rnam> must be a positive small integer (not a list \
(string))
gap> \.\:\=(r, 1000000, 1);
Error, Record Assignment: <rnam> must be a valid rnam (not the integer 1000000\
)
gap> STOP_TEST( "recordname.tst", 1);

0 comments on commit e091884

Please sign in to comment.