From 2a4da23272f5eb388deac97d3e8ee63fb95f0d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 13 Aug 2018 12:30:15 +0200 Subject: [PATCH] [poincare] Fix Integer constructor: avoid creating Integer without setting the digits because at destruction the size() is wrong and corrupt the pool --- poincare/include/poincare/integer.h | 7 +-- poincare/src/integer.cpp | 69 +++++++++++------------------ 2 files changed, 27 insertions(+), 49 deletions(-) diff --git a/poincare/include/poincare/integer.h b/poincare/include/poincare/integer.h index 1c6d9f948..eabe1c80d 100644 --- a/poincare/include/poincare/integer.h +++ b/poincare/include/poincare/integer.h @@ -105,8 +105,6 @@ public: IntegerNode() : NaturalIntegerAbstract(), m_negative(false) {} - virtual void setDigits(native_int_t i); - virtual void setDigits(double_native_int_t i); virtual void setDigits(const native_uint_t * digits, size_t size, bool negative); // Allocation Failure @@ -176,8 +174,6 @@ class AllocationFailureIntegerNode : public AllocationFailureExpressionNode(Number::node()); } Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative); - Integer(size_t size) : Number(TreePool::sharedPool()->createTreeNode(size)) { - } + Integer(size_t size, const native_uint_t * digits, size_t numberOfDigits, bool negative); static Integer addition(const Integer & a, const Integer & b, bool inverseBNegative); size_t numberOfDigits() const { return node()->numberOfDigits(); } uint32_t digit(int i) const { return node()->digit(i); } diff --git a/poincare/src/integer.cpp b/poincare/src/integer.cpp index 2fca84f5e..7a3e55999 100644 --- a/poincare/src/integer.cpp +++ b/poincare/src/integer.cpp @@ -361,35 +361,6 @@ IntegerNode * IntegerNode::FailedAllocationStaticNode() { return &failure; } -void IntegerNode::setDigits(native_int_t i) { - if (i == 0) { - m_numberOfDigits = 0; - m_negative = false; - return; - } - m_negative = i < 0; - m_digits[0] = i < 0 ? -i : i; - m_numberOfDigits = 1; -} - -void IntegerNode::setDigits(double_native_int_t i) { - if (i == 0) { - m_numberOfDigits = 0; - m_negative = false; - return; - } - double_native_uint_t j = i < 0 ? -i : i; - native_uint_t * digits = (native_uint_t *)&j; - native_uint_t leastSignificantDigit = *digits; - native_uint_t mostSignificantDigit = *(digits+1); - m_numberOfDigits = (mostSignificantDigit == 0) ? 1 : 2; - m_digits[0] = leastSignificantDigit; - if (m_numberOfDigits > 1) { - m_digits[1] = mostSignificantDigit; - } - m_negative = i < 0; - -} void IntegerNode::setDigits(const native_uint_t * digits, size_t size, bool negative) { memcpy(m_digits, digits, size*sizeof(native_uint_t)); m_numberOfDigits = size; @@ -459,15 +430,17 @@ int IntegerNode::NaturalOrder(const IntegerNode * i, const IntegerNode * j) { /* Integer */ -Integer::Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative) : - Integer(numberOfDigits*sizeof(native_uint_t)+sizeof(IntegerNode)) -{ +Integer::Integer(size_t size, const native_uint_t * digits, size_t numberOfDigits, bool negative) : Number(TreePool::sharedPool()->createTreeNode(size)) { if (numberOfDigits == 1 && digits[0] == 0) { negative = false; } node()->setDigits(digits, numberOfDigits, negative); } +Integer::Integer(const native_uint_t * digits, size_t numberOfDigits, bool negative) : + Integer(numberOfDigits*sizeof(native_uint_t)+sizeof(IntegerNode), digits, numberOfDigits, negative) +{} + Integer::Integer(const char * digits, size_t length, bool negative) : Number(nullptr) { @@ -494,29 +467,39 @@ Integer::Integer(const char * digits, size_t length, bool negative) : } Integer::Integer(const NaturalIntegerAbstract * naturalInteger) : - Integer(naturalInteger->numberOfDigits()*sizeof(native_uint_t)+sizeof(IntegerNode)) + Integer(naturalInteger->digits(), naturalInteger->numberOfDigits(), false) { - node()->setDigits(naturalInteger->digits(), naturalInteger->numberOfDigits(), false); } Integer::Integer(native_int_t i) : - Integer(i == 0 ? sizeof(IntegerNode) : sizeof(IntegerNode)+sizeof(native_uint_t)) + Number(nullptr) { - node()->setDigits(i); + if (i == 0) { + *this = Integer((const native_uint_t *)nullptr, 0, false); + return; + } + native_uint_t digits[1]; + digits[0] = i < 0 ? -i : i; + *this = Integer(digits, 1, i < 0); } Integer::Integer(double_native_int_t i) : Number(nullptr) { - double_native_uint_t j = i; if (i == 0) { - *this = Integer(sizeof(IntegerNode)); - } else if (j <= 0xFFFFFFFF) { - *this = Integer(sizeof(IntegerNode)+sizeof(native_uint_t)); - } else { - *this = Integer(sizeof(IntegerNode)+2*sizeof(native_uint_t)); + *this = Integer((const native_uint_t *)nullptr, 0, false); + return; } - node()->setDigits(i); + double_native_uint_t j = i < 0 ? -i : i; + native_uint_t * digits = (native_uint_t *)&j; + native_uint_t leastSignificantDigit = *digits; + native_uint_t mostSignificantDigit = *(digits+1); + native_uint_t digitsArray[2] = {leastSignificantDigit, mostSignificantDigit}; + if (mostSignificantDigit == 0) { + *this = Integer(digitsArray, 1, i < 0); + return; + } + *this = Integer(digitsArray, 2, i < 0); } int Integer::extractedInt() const {