From 6352bbcdd92baebcb48aac4e69d2cb69e21244ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 13 Aug 2018 12:20:37 +0200 Subject: [PATCH] [poincare] Fix Rational constructors to prevent malformed Rationals --- poincare/include/poincare/rational.h | 2 +- poincare/src/rational.cpp | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/poincare/include/poincare/rational.h b/poincare/include/poincare/rational.h index 2b1e6c423..7e34ec4b3 100644 --- a/poincare/include/poincare/rational.h +++ b/poincare/include/poincare/rational.h @@ -98,7 +98,7 @@ public: static int NaturalOrder(const Rational i, const Rational j); private: - Rational(size_t size) : Number(TreePool::sharedPool()->createTreeNode(size)) {} + Rational(size_t size, native_uint_t * i, size_t numeratorSize, native_uint_t * j, size_t denominatorSize, bool negative); /* Simplification */ Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const; diff --git a/poincare/src/rational.cpp b/poincare/src/rational.cpp index 179b171c0..e655a4ab8 100644 --- a/poincare/src/rational.cpp +++ b/poincare/src/rational.cpp @@ -156,9 +156,8 @@ Rational::Rational(Integer numerator, Integer denominator) : *this = Rational(RationalNode::FailedAllocationStaticNode()); return; } - *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*(numerator.node()->numberOfDigits()+denominator.node()->numberOfDigits())); bool negative = (numerator.sign() == ExpressionNode::Sign::Positive && denominator.sign() == ExpressionNode::Sign::Negative) || (denominator.sign() == ExpressionNode::Sign::Positive && numerator.sign() == ExpressionNode::Sign::Negative); - node()->setDigits(numerator.node()->digits(), numerator.node()->numberOfDigits(), denominator.node()->digits(), denominator.node()->numberOfDigits(), negative); + *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*(numerator.node()->numberOfDigits()+denominator.node()->numberOfDigits()), numerator.node()->digits(), numerator.node()->numberOfDigits(), denominator.node()->digits(), denominator.node()->numberOfDigits(), negative); return; } @@ -172,30 +171,26 @@ Rational::Rational(const Integer numerator) : } Rational::Rational(const NaturalIntegerAbstract * numerator, bool negative) : Number(nullptr) { - *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*(numerator->numberOfDigits()+1)); native_uint_t one = 1; - node()->setDigits(numerator->digits(), numerator->numberOfDigits(), &one, 1, negative); + *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*(numerator->numberOfDigits()+1), numerator->digits(), numerator->numberOfDigits(), &one, 1, negative); return; } -Rational::Rational(native_int_t i) : Number(nullptr) { - *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2); +Rational::Rational(native_int_t i) : Number(nullptr) { native_uint_t absI = i < 0 ? -i : i; native_uint_t one = 1; - node()->setDigits(&absI, 1, &one, 1, i < 0); + *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2, &absI, 1, &one, 1, i < 0); return; } Rational::Rational(native_int_t i, native_int_t j) : Number(nullptr) { assert(j != 0); - *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2); native_uint_t absI = i < 0 ? -i : i; native_uint_t absJ = j < 0 ? -j : j; - node()->setDigits(&absI, 1, &absJ, 1, (i < 0 && j > 0) || (i > 0 && j < 0)); + *this = Rational(sizeof(RationalNode)+sizeof(native_uint_t)*2, &absI, 1, &absJ, 1, (i < 0 && j > 0) || (i > 0 && j < 0)); return; } - bool Rational::numeratorOrDenominatorIsInfinity() const { return node()->numerator().isInfinity() || node()->denominator().isInfinity(); } @@ -239,6 +234,15 @@ Rational Rational::IntegerPower(const Rational i, const Rational j) { return Rational(newNumerator, newDenominator); } +Rational::Rational(size_t size, native_uint_t * i, size_t numeratorSize, native_uint_t * j, size_t denominatorSize, bool negative) : + Number(nullptr) +{ + assert(j != 0); + TreeNode * node = TreePool::sharedPool()->createTreeNode(size); + TreeByReference::setIdentifierAndRetain(node->identifier()); + static_cast(node)->setDigits(i, numeratorSize, j, denominatorSize, negative); +} + Expression Rational::shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) const { if (sign() == ExpressionNode::Sign::Negative) { Expression abs = setSign(ExpressionNode::Sign::Positive);