GP-2785 Match up token field bounds checking between compilers

This commit is contained in:
caheckman 2020-03-25 11:17:24 -04:00
parent 1cdb59e1bb
commit e0a5cf1720
3 changed files with 38 additions and 12 deletions

View file

@ -2479,6 +2479,16 @@ TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz,int4 endian)
void SleighCompile::addTokenField(TokenSymbol *sym,FieldQuality *qual) void SleighCompile::addTokenField(TokenSymbol *sym,FieldQuality *qual)
{ {
if (qual->high < qual->low) {
ostringstream s;
s << "Field '" << qual->name << "' starts at " << qual->low << " and ends at " << qual->high;
reportError(getCurrentLocation(), s.str());
}
if (sym->getToken()->getSize() * 8 <= qual->high) {
ostringstream s;
s << "Field '" << qual->name << "' high must be less than token size";
reportError(getCurrentLocation(), s.str());
}
TokenField *field = new TokenField(sym->getToken(),qual->signext,qual->low,qual->high); TokenField *field = new TokenField(sym->getToken(),qual->signext,qual->low,qual->high);
addSymbol(new ValueSymbol(qual->name,field)); addSymbol(new ValueSymbol(qual->name,field));
delete qual; delete qual;
@ -2491,6 +2501,16 @@ void SleighCompile::addTokenField(TokenSymbol *sym,FieldQuality *qual)
bool SleighCompile::addContextField(VarnodeSymbol *sym,FieldQuality *qual) bool SleighCompile::addContextField(VarnodeSymbol *sym,FieldQuality *qual)
{ {
if (qual->high < qual->low) {
ostringstream s;
s << "Context field '" << qual->name << "' starts at " << qual->low << " and ends at " << qual->high;
reportError(getCurrentLocation(), s.str());
}
if (sym->getSize() * 8 <= qual->high) {
ostringstream s;
s << "Context field '" << qual->name << "' high must be less than context size";
reportError(getCurrentLocation(), s.str());
}
if (contextlock) if (contextlock)
return false; // Context layout has already been satisfied return false; // Context layout has already been satisfied

View file

@ -212,23 +212,14 @@ fielddef
} }
: ^(t=OP_FIELDDEF n=unbound_identifier["field"] s=integer e=integer { : ^(t=OP_FIELDDEF n=unbound_identifier["field"] s=integer e=integer {
if (n != null) { if (n != null) {
long start = $s.value.longValue();
long finish = $e.value.longValue();
if (finish < start) {
reportError(find($t), "field '" + $n.value.getText() + "' starts at " + start + " and ends at " + finish);
}
$fielddef::fieldQuality = new FieldQuality($n.value.getText(), find($t), $s.value.longValue(), $e.value.longValue()); $fielddef::fieldQuality = new FieldQuality($n.value.getText(), find($t), $s.value.longValue(), $e.value.longValue());
} }
} fieldmods) { } fieldmods) {
if ($fielddef.size() > 0 && $fielddef::fieldQuality != null) { if ($fielddef.size() > 0 && $fielddef::fieldQuality != null) {
if ($tokendef.size() > 0 && $tokendef::tokenSymbol != null) { if ($tokendef.size() > 0 && $tokendef::tokenSymbol != null) {
if ($tokendef::tokenSymbol.getToken().getSize()*8 <= $fielddef::fieldQuality.high) { sc.addTokenField(find(n), $tokendef::tokenSymbol, $fielddef::fieldQuality);
reportError(find($t), "field high must be less than token size");
} else {
sc.addTokenField(find(n), $tokendef::tokenSymbol, $fielddef::fieldQuality);
}
} else if ($contextdef.size() > 0 && $contextdef::varnode != null) { } else if ($contextdef.size() > 0 && $contextdef::varnode != null) {
if (!sc.addContextField($contextdef::varnode, $fielddef::fieldQuality)) { if (!sc.addContextField(find(n), $contextdef::varnode, $fielddef::fieldQuality)) {
reportError(find($t), "all context definitions must come before constructors"); reportError(find($t), "all context definitions must come before constructors");
} }
} }

View file

@ -923,13 +923,28 @@ public class SleighCompile extends SleighBase {
public void addTokenField(Location location, TokenSymbol sym, FieldQuality qual) { public void addTokenField(Location location, TokenSymbol sym, FieldQuality qual) {
entry("addTokenField", location, sym, qual); entry("addTokenField", location, sym, qual);
if (qual.high < qual.low) {
reportError(location, "Field '" + qual.name + "' starts at " +
Integer.toString(qual.low) + " and ends at " + Integer.toString(qual.high));
}
if (sym.getToken().getSize() * 8 <= qual.high) {
reportError(location, "Field '" + qual.name + "' high must be less than token size");
}
TokenField field = TokenField field =
new TokenField(location, sym.getToken(), qual.signext, qual.low, qual.high); new TokenField(location, sym.getToken(), qual.signext, qual.low, qual.high);
addSymbol(new ValueSymbol(location, qual.name, field)); addSymbol(new ValueSymbol(location, qual.name, field));
} }
public boolean addContextField(VarnodeSymbol sym, FieldQuality qual) { public boolean addContextField(Location location, VarnodeSymbol sym, FieldQuality qual) {
entry("addContextField", sym, qual); entry("addContextField", sym, qual);
if (qual.high < qual.low) {
reportError(location, "Context field '" + qual.name + "' starts at " +
Integer.toString(qual.low) + " and ends at " + Integer.toString(qual.high));
}
if (sym.getSize() * 8 <= qual.high) {
reportError(location,
"Context field '" + qual.name + "' high must be less than context size");
}
if (contextlock) { if (contextlock) {
return false; // Context layout has already been satisfied return false; // Context layout has already been satisfied
} }