[poincare] Never return nullptr when creating a expression to avoid

nullptr dereference

Change-Id: Ie7976a8ee86c82283ebcbffc28fe902ddfb7a952
This commit is contained in:
Émilie Feral
2017-03-28 12:04:52 +02:00
parent d1b382b23d
commit fa2ee9e624
10 changed files with 16 additions and 24 deletions

View File

@@ -23,7 +23,6 @@ public:
static constexpr uint16_t k_maxNumberOfMatrixExpressions = 10;
static Complex * defaultExpression();
private:
static Complex * nanExpression();
int symbolIndex(const Symbol * symbol) const;
Expression * m_expressions[k_maxNumberOfScalarExpressions];
Complex m_pi;

View File

@@ -43,9 +43,6 @@ Expression * BinaryOperation::privateEvaluate(Context& context, AngleUnit angleU
assert(angleUnit != AngleUnit::Default);
Expression * leftOperandEvalutation = m_operands[0]->evaluate(context, angleUnit);
Expression * rightOperandEvalutation = m_operands[1]->evaluate(context, angleUnit);
if (leftOperandEvalutation == nullptr || rightOperandEvalutation == nullptr) {
return nullptr;
}
Expression * result = nullptr;
switch (leftOperandEvalutation->type()) {
case Type::Complex:
@@ -58,6 +55,7 @@ Expression * BinaryOperation::privateEvaluate(Context& context, AngleUnit angleU
result = evaluateOnComplexAndMatrix((Complex *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit);
break;
default:
result = new Complex(Complex::Float(NAN));
break;
}
}
@@ -72,11 +70,13 @@ Expression * BinaryOperation::privateEvaluate(Context& context, AngleUnit angleU
result = evaluateOnMatrices((Matrix *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit);
break;
default:
result = new Complex(Complex::Float(NAN));
break;
}
}
break;
default:
result = new Complex(Complex::Float(NAN));
break;
}
delete leftOperandEvalutation;
@@ -108,7 +108,7 @@ Expression * BinaryOperation::evaluateOnComplexAndMatrix(Complex * c, Matrix * m
Expression * BinaryOperation::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) {
return nullptr;
return new Complex(Complex::Float(NAN));
}
Expression ** operands = (Expression **)malloc(m->numberOfRows() * m->numberOfColumns()*sizeof(Expression *));
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {

View File

@@ -141,7 +141,7 @@ exp:
| MINUS exp { $$ = new Poincare::Opposite($2, false); }
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Poincare::Parenthesis($2, false); }
| LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Poincare::Matrix($2); }
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { if (!$1->isValidNumberOfArguments($3->numberOfOperands())) { $$ = nullptr;} else {$$ = $1; $1->setArgument($3, true); delete $3;} }
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { if (!$1->isValidNumberOfArguments($3->numberOfOperands())) { $$ = new Poincare::Complex(Poincare::Complex::Float(NAN));} else {$$ = $1; $1->setArgument($3, true); delete $3;} }
;
%%

View File

@@ -38,12 +38,12 @@ Expression * Fraction::evaluateOnComplex(Complex * c, Complex * d, Context& cont
}
Expression * Fraction::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
return nullptr;
return new Complex(Complex::Float(NAN));
}
Expression * Fraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
if (m->numberOfColumns() != n->numberOfColumns()) {
return nullptr;
return new Complex(Complex::Float(NAN));
}
if (fabsf(n->determinant(context, angleUnit)) <= FLT_EPSILON) {
return new Complex(Complex::Float(NAN));

View File

@@ -28,11 +28,6 @@ Complex * GlobalContext::defaultExpression() {
return defaultExpression;
}
Complex * GlobalContext::nanExpression() {
static Complex * nanExpression = new Complex(Complex::Float(NAN));
return nanExpression;
}
int GlobalContext::symbolIndex(const Symbol * symbol) const {
int index = symbol->name() - 'A';
return index;
@@ -47,7 +42,7 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) {
}
int index = symbolIndex(symbol);
if (index < 0 || index >= k_maxNumberOfScalarExpressions) {
return nanExpression();
return nullptr;
}
if (m_expressions[index] == nullptr) {
return defaultExpression();

View File

@@ -225,7 +225,7 @@ float Matrix::determinant(Context& context, AngleUnit angleUnit) const {
Expression * Matrix::createInverse(Context& context, AngleUnit angleUnit) const {
if (numberOfColumns() != numberOfRows()) {
return nullptr;
return new Complex(Complex::Float(NAN));
}
int dim = numberOfRows();
/* Create the matrix inv = (A|I) with A the input matrix and I the dim identity matrix */

View File

@@ -36,7 +36,7 @@ Expression * MatrixDimension::privateEvaluate(Context& context, AngleUnit angleU
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Complex) {
delete evaluation;
return nullptr;
return new Complex(Complex::Float(NAN));
}
Expression * dimension = ((Matrix *)evaluation)->createDimensionMatrix(context, angleUnit);
delete evaluation;

View File

@@ -43,7 +43,7 @@ Expression * Multiplication::evaluateOnComplex(Complex * c, Complex * d, Context
Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
if (m->numberOfColumns() != n->numberOfRows()) {
return nullptr;
return new Complex(Complex::Float(NAN));
}
Expression ** operands = (Expression **)malloc(m->numberOfRows() * n->numberOfColumns()*sizeof(Expression *));
for (int i = 0; i < m->numberOfRows(); i++) {

View File

@@ -39,9 +39,6 @@ Expression * Opposite::clone() const {
Expression * Opposite::privateEvaluate(Context& context, AngleUnit angleUnit) const {
assert(angleUnit != AngleUnit::Default);
Expression * operandEvalutation = m_operand->evaluate(context, angleUnit);
if (operandEvalutation == nullptr) {
return nullptr;
}
Expression * result = nullptr;
switch (operandEvalutation->type()) {
case Type::Complex:
@@ -51,6 +48,7 @@ Expression * Opposite::privateEvaluate(Context& context, AngleUnit angleUnit) co
result = evaluateOnMatrix((Matrix *)operandEvalutation, context, angleUnit);
break;
default:
result = new Complex(Complex::Float(NAN));
break;
}
delete operandEvalutation;

View File

@@ -53,10 +53,10 @@ Expression * Power::evaluateOnComplex(Complex * c, Complex * d, Context& context
Expression * Power::evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context& context, AngleUnit angleUnit) const {
if (m_operands[1]->type() != Expression::Type::Integer) {
return nullptr;
return new Complex(Complex::Float(NAN));
}
if (m->numberOfColumns() != m->numberOfRows()) {
return nullptr;
return new Complex(Complex::Float(NAN));
}
// TODO: return identity matrix if i == 0
int power = c->approximate(context, angleUnit);
@@ -75,11 +75,11 @@ Expression * Power::evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context&
}
Expression * Power::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
return nullptr;
return new Complex(Complex::Float(NAN));
}
Expression * Power::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
return nullptr;
return new Complex(Complex::Float(NAN));
}
}