[dali_1.3.10] Merge branch 'devel/master' 24/169124/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 2 Feb 2018 10:29:22 +0000 (10:29 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 2 Feb 2018 10:29:22 +0000 (10:29 +0000)
Change-Id: I13d7a79df19bf81981b3d1bfef40c554d87ad21f

automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 6c63ce1..ad36607 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
+#include <dali-toolkit/internal/text/text-controller-impl.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -656,4 +657,36 @@ int UtcDaliTextControllerSetGetLineSpacingProperty(void)
 
   END_TEST;
 
-}
\ No newline at end of file
+}
+
+int UtcDaliTextControllerCheckBufferIndices(void)
+{
+  tet_infoline(" UtcDaliTextControllerCheckBufferIndices");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  ConfigureTextLabel(controller);
+
+  // Set the text
+  const std::string text("A Quick Brown Fox Jumps Over The Lazy Dog");
+  controller->SetText(text);
+
+  // Get the implementation of the text controller
+  Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+
+  // Tweak some parameters to make the indices to access the text buffer invalid
+  mImpl.mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl.mModel->mLogicalModel->mText.Count() * 10u;
+  mImpl.mTextUpdateInfo.mNumberOfCharactersToRemove = 0u;
+  mImpl.mTextUpdateInfo.mPreviousNumberOfCharacters = 0u;
+  mImpl.mOperationsPending = Controller::ALL_OPERATIONS;
+
+  // Perform a relayout
+  const Size size( Dali::Stage::GetCurrent().GetSize() );
+  controller->Relayout(size);
+
+  tet_result(TET_PASS);
+
+  END_TEST;
+}
index dd429a1..af257ff 100644 (file)
@@ -109,7 +109,8 @@ struct Engine::Impl
   Impl()
   : mLayout( Layout::Engine::SINGLE_LINE_BOX ),
     mCursorWidth( CURSOR_WIDTH ),
-    mDefaultLineSpacing( LINE_SPACING )
+    mDefaultLineSpacing( LINE_SPACING ),
+    mPreviousCharacterExtraWidth( 0.0f )
   {
   }
 
@@ -345,6 +346,7 @@ struct Engine::Impl
 
             const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
             tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
+            tmpExtraWidth = std::max( mPreviousCharacterExtraWidth - glyphMetrics.advance, tmpExtraWidth );
           }
         }
         else
@@ -358,6 +360,7 @@ struct Engine::Impl
 
               const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
               tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
+              tmpExtraWidth = std::max( mPreviousCharacterExtraWidth - glyphMetrics.advance, tmpExtraWidth );
             }
             else // LTR
             {
@@ -385,6 +388,7 @@ struct Engine::Impl
 
               const float extraWidth = glyphMetrics.xBearing + glyphMetrics.width - glyphMetrics.advance;
               tmpExtraWidth = ( 0.f < extraWidth ) ? extraWidth : 0.f;
+              tmpExtraWidth = std::max( mPreviousCharacterExtraWidth - glyphMetrics.advance, tmpExtraWidth );
             }
           }
         }
@@ -393,6 +397,9 @@ struct Engine::Impl
         tmpLineLayout.wsLengthEndOfLine = 0.f;
       }
 
+      // Save the current extra width to compare with the next one
+      mPreviousCharacterExtraWidth = tmpExtraWidth;
+
       // Check if the accumulated length fits in the width of the box.
       if( ( completelyFill || isMultiline ) && !isWhiteSpace &&
           ( tmpExtraBearing + lineLayout.length + lineLayout.wsLengthEndOfLine + tmpLineLayout.length + tmpExtraWidth > parameters.boundingBox.width ) )
@@ -1217,6 +1224,7 @@ struct Engine::Impl
   Type mLayout;
   float mCursorWidth;
   float mDefaultLineSpacing;
+  float mPreviousCharacterExtraWidth;
 
   IntrusivePtr<Metrics> mMetrics;
 };
index 3e63578..b40dba5 100644 (file)
@@ -811,6 +811,36 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   Length paragraphCharacters = 0u;
 
   CalculateTextUpdateIndices( paragraphCharacters );
+
+  // Check whether the indices for updating the text is valid
+  if ( numberOfCharacters > 0u &&
+       ( mTextUpdateInfo.mParagraphCharacterIndex >= numberOfCharacters ||
+         mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters ) )
+  {
+    std::string currentText;
+    Utf32ToUtf8( mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText );
+
+    DALI_LOG_ERROR( "Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n" );
+    DALI_LOG_ERROR( "Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str() );
+
+    // Dump mTextUpdateInfo
+    DALI_LOG_ERROR( "Dump mTextUpdateInfo:\n" );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mCharacterIndex = %u\n", mTextUpdateInfo.mCharacterIndex );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", mTextUpdateInfo.mNumberOfCharactersToRemove );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", mTextUpdateInfo.mNumberOfCharactersToAdd );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", mTextUpdateInfo.mPreviousNumberOfCharacters );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mParagraphCharacterIndex = %u\n", mTextUpdateInfo.mParagraphCharacterIndex );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", mTextUpdateInfo.mRequestedNumberOfCharacters );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mStartGlyphIndex = %u\n", mTextUpdateInfo.mStartGlyphIndex );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mStartLineIndex = %u\n", mTextUpdateInfo.mStartLineIndex );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", mTextUpdateInfo.mEstimatedNumberOfLines );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mClearAll = %d\n", mTextUpdateInfo.mClearAll );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mFullRelayoutNeeded = %d\n", mTextUpdateInfo.mFullRelayoutNeeded );
+    DALI_LOG_ERROR( "     mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", mTextUpdateInfo.mIsLastCharacterNewParagraph );
+
+    return false;
+  }
+
   startIndex = mTextUpdateInfo.mParagraphCharacterIndex;
 
   if( mTextUpdateInfo.mClearAll ||
index f07e955..52dad25 100644 (file)
@@ -712,6 +712,18 @@ struct Controller::Impl
    */
   void ScrollTextToMatchCursor( const CursorInfo& cursorInfo );
 
+public:
+
+  /**
+   * @brief Gets implementation from the controller handle.
+   * @param controller The text controller
+   * @return The implementation of the Controller
+   */
+  static Impl& GetImplementation( Text::Controller& controller )
+  {
+    return *controller.mImpl;
+  }
+
 private:
   // Declared private and left undefined to avoid copies.
   Impl( const Impl& );
index 279f03e..136770c 100755 (executable)
@@ -3441,6 +3441,22 @@ bool Controller::DoRelayout( const Size& size,
 
     const CharacterIndex lastIndex = startIndex + ( ( requestedNumberOfCharacters > 0u ) ? requestedNumberOfCharacters - 1u : 0u );
     const GlyphIndex startGlyphIndex = mImpl->mTextUpdateInfo.mStartGlyphIndex;
+
+    // Make sure the index is not out of bound
+    if ( charactersToGlyph.Count() != glyphsPerCharacter.Count() ||
+         requestedNumberOfCharacters > charactersToGlyph.Count() ||
+         ( lastIndex >= charactersToGlyph.Count() && charactersToGlyph.Count() > 0u ) )
+    {
+      std::string currentText;
+      GetText( currentText );
+
+      DALI_LOG_ERROR( "Controller::DoRelayout: Attempting to access invalid buffer\n" );
+      DALI_LOG_ERROR( "Current text is: %s\n", currentText.c_str() );
+      DALI_LOG_ERROR( "startIndex: %u, lastIndex: %u, requestedNumberOfCharacters: %u, charactersToGlyph.Count = %lu, glyphsPerCharacter.Count = %lu\n", startIndex, lastIndex, requestedNumberOfCharacters, charactersToGlyph.Count(), glyphsPerCharacter.Count());
+
+      return false;
+    }
+
     const Length numberOfGlyphs = ( requestedNumberOfCharacters > 0u ) ? *( charactersToGlyphBuffer + lastIndex ) + *( glyphsPerCharacterBuffer + lastIndex ) - startGlyphIndex : 0u;
     const Length totalNumberOfGlyphs = mImpl->mModel->mVisualModel->mGlyphs.Count();
 
index 415b8f5..85c6818 100755 (executable)
@@ -1497,9 +1497,12 @@ protected: // Destructor.
    */
   virtual ~Controller();
 
+public:
+
+  struct Impl; ///< Made public for testing purposes
+
 private:
 
-  struct Impl;
   Impl* mImpl;
 };
 
index eb5e972..ae7edb7 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 9;
+const unsigned int TOOLKIT_MICRO_VERSION = 10;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index af1843c..62a490b 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.3.9
+Version:    1.3.10
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT