Fix various errors triggered by fuzzing

This commit is contained in:
drmortalwombat 2021-10-17 18:20:44 +02:00
parent 5010043fc4
commit 6481e119e4
9 changed files with 101 additions and 33 deletions

View File

@ -142,11 +142,12 @@ Expression* Expression::LogicInvertExpression(void)
{
Expression* ex = new Expression(mLocation, EX_LOGICAL_NOT);
ex->mLeft = this;
ex->mDecType = TheBoolTypeDeclaration;
return ex;
}
}
Expression* Expression::ConstantFold(void)
Expression* Expression::ConstantFold(Errors * errors)
{
if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
{
@ -249,7 +250,7 @@ Expression* Expression::ConstantFold(void)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER && mRight->mDecValue->mType == DT_CONST_INTEGER)
{
int64 ival, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
int64 ival = 0, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
switch (mToken)
{
@ -263,10 +264,16 @@ Expression* Expression::ConstantFold(void)
ival = ileft * iright;
break;
case TK_DIV:
ival = ileft / iright;
if (iright == 0)
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
else
ival = ileft / iright;
break;
case TK_MOD:
ival = ileft % iright;
if (iright == 0)
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
else
ival = ileft % iright;
break;
case TK_LEFT_SHIFT:
ival = ileft << iright;
@ -498,6 +505,7 @@ bool Declaration::IsNumericType(void) const
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration;
Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
void InitDeclarations(void)
{
@ -510,6 +518,17 @@ void InitDeclarations(void)
TheVoidPointerTypeDeclaration->mSize = 2;
TheVoidPointerTypeDeclaration->mFlags = DTF_DEFINED;
TheVoidFunctionTypeDeclaration = new Declaration(noloc, DT_TYPE_FUNCTION);
TheVoidFunctionTypeDeclaration->mBase = TheVoidTypeDeclaration;
TheVoidFunctionTypeDeclaration->mSize = 2;
TheVoidFunctionTypeDeclaration->mFlags = DTF_DEFINED;
TheConstVoidValueDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
TheVoidFunctionTypeDeclaration->mBase = TheVoidTypeDeclaration;
TheVoidFunctionTypeDeclaration->mSize = 2;
TheVoidFunctionTypeDeclaration->mInteger = 0;
TheVoidFunctionTypeDeclaration->mFlags = DTF_DEFINED;
TheSignedIntTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
TheSignedIntTypeDeclaration->mSize = 2;
TheSignedIntTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;

View File

@ -150,7 +150,7 @@ public:
bool mConst;
Expression* LogicInvertExpression(void);
Expression* ConstantFold(void);
Expression* ConstantFold(Errors * errors);
};
class Declaration
@ -188,3 +188,5 @@ void InitDeclarations(void);
extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration;
extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration;
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;

View File

@ -27,7 +27,7 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char
printf("%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
if (mErrorCount > 10)
exit(10);
exit(20);
}

View File

@ -31,6 +31,7 @@ enum ErrorID
EERR_CONSTANT_INITIALIZER,
EERR_CONSTANT_TYPE,
EERR_VARIABLE_TYPE,
EERR_INVALID_VALUE,
EERR_INCOMPATIBLE_TYPES,
EERR_INCOMPATIBLE_OPERATOR,
EERR_CONST_ASSIGN,

View File

@ -168,7 +168,7 @@ void GlobalAnalyzer::AnalyzeAssembler(Expression* exp, Declaration* procDec)
if (procDec)
procDec->mComplexity += 2;
if (exp->mLeft)
if (exp->mLeft && exp->mLeft->mDecValue)
{
Declaration* adec = exp->mLeft->mDecValue;
if (adec->mType == DT_LABEL_REF)
@ -306,7 +306,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
case EX_SEQUENCE:
do
{
ldec = Analyze(exp->mLeft, procDec);
if (exp->mLeft)
ldec = Analyze(exp->mLeft, procDec);
exp = exp->mRight;
} while (exp);
break;

View File

@ -277,7 +277,9 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
case ASMIM_IMPLIED:
break;
case ASMIM_IMMEDIATE:
if (aexp->mType == DT_CONST_INTEGER)
if (!aexp)
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
else if (aexp->mType == DT_CONST_INTEGER)
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
else if (aexp->mType == DT_LABEL_REF)
{
@ -346,7 +348,9 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
case ASMIM_ZERO_PAGE_X:
case ASMIM_INDIRECT_X:
case ASMIM_INDIRECT_Y:
if (aexp->mType == DT_VARIABLE_REF)
if (!aexp)
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
else if (aexp->mType == DT_VARIABLE_REF)
{
if (refvars)
{
@ -405,7 +409,9 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
case ASMIM_INDIRECT:
case ASMIM_ABSOLUTE_X:
case ASMIM_ABSOLUTE_Y:
if (aexp->mType == DT_CONST_INTEGER)
if (!aexp)
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
else if (aexp->mType == DT_CONST_INTEGER)
{
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8;
@ -535,7 +541,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
}
break;
case ASMIM_RELATIVE:
d[offset] = aexp->mInteger - offset - 1;
if (!aexp)
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
else
d[offset] = aexp->mInteger - offset - 1;
offset++;
break;
}
@ -928,7 +937,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_ASSIGNMENT:
{
if (exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
if (exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
{
vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper, &vl);
@ -3173,7 +3182,8 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
exitBlock->Append(ins);
exitBlock->Close(nullptr, nullptr);
proc->Close();
if (mErrors->mErrorCount == 0)
proc->Close();
return proc;
}

View File

@ -891,6 +891,7 @@ Expression* Parser::ParseDeclarationExpression(void)
nexp->mLeft = new Expression(dec->mLocation, EX_VARIABLE);
nexp->mLeft->mDecValue = dec;
nexp->mLeft->mDecType = dec->mBase;
nexp->mDecType = nexp->mLeft->mDecType;
nexp->mRight = dec->mValue;
@ -1152,7 +1153,7 @@ Expression* Parser::ParseSimpleExpression(void)
nexp->mDecType = exp->mDecType;
nexp->mLeft = exp;
nexp->mRight = ParsePrefixExpression();
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
break;
default:
@ -1202,7 +1203,10 @@ Expression* Parser::ParsePostfixExpression(void)
{
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call");
exp->mDecType = TheVoidFunctionTypeDeclaration;
}
mScanner->NextToken();
Expression* nexp = new Expression(mScanner->mLocation, EX_CALL);
@ -1332,7 +1336,10 @@ Expression* Parser::ParsePrefixExpression(void)
nexp->mDecType = nexp->mLeft->mDecType->mBase;
}
else
{
mErrors->Error(nexp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Pointer or array type expected");
nexp->mDecType = TheVoidTypeDeclaration;
}
}
else if (nexp->mToken == TK_BINARY_AND)
{
@ -1344,7 +1351,7 @@ Expression* Parser::ParsePrefixExpression(void)
else
nexp->mDecType = nexp->mLeft->mDecType;
}
return nexp->ConstantFold();
return nexp->ConstantFold(mErrors);
}
else
return ParsePostfixExpression();
@ -1367,7 +1374,7 @@ Expression* Parser::ParseMulExpression(void)
else
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1407,7 +1414,7 @@ Expression* Parser::ParseAddExpression(void)
else
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1426,7 +1433,7 @@ Expression* Parser::ParseShiftExpression(void)
nexp->mRight = ParseAddExpression();
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1445,7 +1452,7 @@ Expression* Parser::ParseRelationalExpression(void)
nexp->mRight = ParseShiftExpression();
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1464,7 +1471,7 @@ Expression* Parser::ParseBinaryAndExpression(void)
nexp->mRight = ParseRelationalExpression();
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1482,7 +1489,7 @@ Expression* Parser::ParseBinaryXorExpression(void)
mScanner->NextToken();
nexp->mRight = ParseBinaryAndExpression();
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1500,7 +1507,7 @@ Expression* Parser::ParseBinaryOrExpression(void)
mScanner->NextToken();
nexp->mRight = ParseBinaryXorExpression();
nexp->mDecType = exp->mDecType;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1518,7 +1525,7 @@ Expression* Parser::ParseLogicAndExpression(void)
mScanner->NextToken();
nexp->mRight = ParseBinaryOrExpression();
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1536,7 +1543,7 @@ Expression* Parser::ParseLogicOrExpression(void)
mScanner->NextToken();
nexp->mRight = ParseLogicAndExpression();
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
@ -1558,6 +1565,7 @@ Expression* Parser::ParseConditionalExpression(void)
ConsumeToken(TK_COLON);
texp->mRight = ParseConditionalExpression();
nexp->mDecType = texp->mLeft->mDecType;
exp = nexp;
}
@ -1599,6 +1607,7 @@ Expression* Parser::ParseAssignmentExpression(void)
nexp->mRight = ParseAssignmentExpression();
nexp->mDecType = exp->mDecType;
exp = nexp;
assert(exp->mDecType);
}
return exp;
@ -1796,6 +1805,7 @@ Expression* Parser::ParseStatement(void)
exp = new Expression(mScanner->mLocation, EX_CONTINUE);
break;
case TK_SEMICOLON:
exp = new Expression(mScanner->mLocation, EX_VOID);
break;
case TK_ASM:
mScanner->NextToken();
@ -1808,6 +1818,11 @@ Expression* Parser::ParseStatement(void)
else
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "'}' expected");
}
else
{
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "'{' expected");
exp = new Expression(mScanner->mLocation, EX_VOID);
}
break;
default:
exp = ParseExpression();
@ -1816,6 +1831,8 @@ Expression* Parser::ParseStatement(void)
mScanner->NextToken();
}
assert(exp);
return exp;
}
@ -2045,6 +2062,7 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
{
exp = new Expression(mScanner->mLocation, EX_VOID);
exp->mDecType = TheVoidTypeDeclaration;
exp->mDecValue = TheConstVoidValueDeclaration;
}
return exp;
@ -2060,7 +2078,7 @@ Expression* Parser::ParseAssemblerMulOperand(void)
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseAssemblerBaseOperand();
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
}
@ -2075,7 +2093,11 @@ Expression* Parser::ParseAssemblerAddOperand(void)
nexp->mLeft = exp;
mScanner->NextToken();
nexp->mRight = ParseAssemblerMulOperand();
if (nexp->mLeft->mDecValue->mType == DT_VARIABLE || nexp->mLeft->mDecValue->mType == DT_ARGUMENT)
if (!nexp->mLeft->mDecValue || !nexp->mRight->mDecValue)
{
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid assembler operand");
}
else if (nexp->mLeft->mDecValue->mType == DT_VARIABLE || nexp->mLeft->mDecValue->mType == DT_ARGUMENT)
{
if (nexp->mRight->mDecValue->mType == DT_CONST_INTEGER)
{
@ -2115,7 +2137,7 @@ Expression* Parser::ParseAssemblerAddOperand(void)
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Integer offset expected");
}
else
exp = nexp->ConstantFold();
exp = nexp->ConstantFold(mErrors);
}
return exp;
}

View File

@ -50,7 +50,10 @@ SourceFile::~SourceFile(void)
bool SourceFile::Open(const char* name, const char* path)
{
char fname[200];
char fname[220];
if (strlen(name) + strlen(path) > 200)
return false;
strcpy_s(fname, path);
int n = strlen(fname);
@ -142,6 +145,12 @@ bool Preprocessor::NextLine(void)
bool Preprocessor::OpenSource(const char * reason, const char* name, bool local)
{
if (strlen(name) > 200)
{
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Source file path exceeds max path length");
return false;
}
if (mSource)
mSource->mLocation = mLocation;
@ -154,7 +163,7 @@ bool Preprocessor::OpenSource(const char * reason, const char* name, bool local)
if (!ok && local && mSource)
{
char lpath[200];
char lpath[220];
strcpy_s(lpath, mSource->mFileName);
int i = strlen(lpath);
while (i > 0 && lpath[i - 1] != '/')

View File

@ -985,7 +985,8 @@ void Scanner::NextRawToken(void)
while (NextChar() && IsAlpha(mTokenChar))
{
tkprep[n++] = mTokenChar;
if (n < 127)
tkprep[n++] = mTokenChar;
}
tkprep[n] = 0;
@ -1070,18 +1071,21 @@ void Scanner::NextRawToken(void)
else if (mTokenChar >= 'A' && mTokenChar <= 'Z' || mTokenChar >= 'a' && mTokenChar <= 'z' || mTokenChar == '_')
{
int n = 0;
char tkident[128];
char tkident[256];
for (;;)
{
if (IsIdentChar(mTokenChar))
{
tkident[n++] = mTokenChar;
if (n < 255)
tkident[n++] = mTokenChar;
NextChar();
}
else
break;
}
tkident[n] = 0;
if (n == 256)
Error("Identifier exceeds max character limit");
if (!strcmp(tkident, "true"))
mToken = TK_TRUE;