From e49dc0875900b943905c4f79464ee8ee3c3a8378 Mon Sep 17 00:00:00 2001 From: Gabriel Ozouf Date: Mon, 6 Jul 2020 15:09:56 +0200 Subject: [PATCH] [escher/expression_field] Fixed dumpLayout Closing the Calculation app because of a full pool would crash the device, by attempting to dump a layout with no node. Change-Id: Ic926da61ae93f47eb576848788e1de5e3f94f5bb --- escher/include/escher/expression_view.h | 1 + escher/include/escher/layout_field.h | 1 + escher/src/expression_field.cpp | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/escher/include/escher/expression_view.h b/escher/include/escher/expression_view.h index 4e4a4b901..c177a48d2 100644 --- a/escher/include/escher/expression_view.h +++ b/escher/include/escher/expression_view.h @@ -26,6 +26,7 @@ public: KDSize minimalSizeForOptimalDisplay() const override; KDPoint drawingOrigin() const; KDPoint absoluteDrawingOrigin() const; + bool layoutHasNode() const { return Poincare::TreeNode::IsValidIdentifier(m_layout.identifier()) && !m_layout.wasErasedByException(); } protected: /* Warning: we do not need to delete the previous expression layout when * deleting object or setting a new expression layout. Indeed, the expression diff --git a/escher/include/escher/layout_field.h b/escher/include/escher/layout_field.h index a39e585ba..908d27f3f 100644 --- a/escher/include/escher/layout_field.h +++ b/escher/include/escher/layout_field.h @@ -32,6 +32,7 @@ public: } bool hasText() const { return layout().hasText(); } Poincare::Layout layout() const { return m_contentView.expressionView()->layout(); } + bool layoutHasNode() const { return m_contentView.expressionView()->layoutHasNode(); } CodePoint XNTCodePoint(CodePoint defaultXNTCodePoint) override; void putCursorRightOfLayout(); void setInsertionCursorEvent(Ion::Events::Event event) { m_insertionCursorEvent = event; } diff --git a/escher/src/expression_field.cpp b/escher/src/expression_field.cpp index 599f69b7f..46d09b611 100644 --- a/escher/src/expression_field.cpp +++ b/escher/src/expression_field.cpp @@ -136,6 +136,16 @@ size_t ExpressionField::dumpLayout(char * buffer, size_t bufferSize) const { * has changed and invalidate the data.*/ returnValue = 0; } else { + /* dumpLayout will be called whenever Calculation exits, event when an + * exception occurs. We thus need to check the validity of the layout we + * are dumping (m_layoutField.m_contentView.m_expressionView.m_layout). + * However, attempting to get a handle on a layout that has been erased + * will crash the program. We need the check to be performed on the + * original object in expressionView. */ + if (!m_layoutField.layoutHasNode()) { + buffer[0] = 0; + return 0; + } size = m_layoutField.layout().size(); currentLayout = reinterpret_cast(m_layoutField.layout().node()); returnValue = size;