tdf#161035: The previous bookmarks can legitimately be not processed

The enumeration may be called for a partial paragraph selection, and
then the bookmarks prior to the selection are not processed.

Change-Id: Ib725ffb320ec5a81b39ce77f06392a82bd6d8ee0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167720
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167754
Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
diff --git a/sw/qa/extras/unowriter/data/tdf161035.fodt b/sw/qa/extras/unowriter/data/tdf161035.fodt
new file mode 100644
index 0000000..8f1d53b
--- /dev/null
+++ b/sw/qa/extras/unowriter/data/tdf161035.fodt
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>

<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
 <office:body>
  <office:text>
   <text:p>Lorem <text:bookmark text:name="Bookmark"/>ipsum.</text:p>
  </office:text>
 </office:body>
</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index 80b9e55..7175e70 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -1222,6 +1222,33 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf160278)
    CPPUNIT_ASSERT_EQUAL(u"12test"_ustr, xText->getString());
}

CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf161035)
{
    // Given a paragraph with a bookmark:
    createSwDoc("tdf161035.fodt");
    auto xModel = mxComponent.queryThrow<frame::XModel>();

    // Create a text view cursor in the paragraph.
    auto xController = xModel->getCurrentController().queryThrow<text::XTextViewCursorSupplier>();
    auto xViewCursor = xController->getViewCursor();
    CPPUNIT_ASSERT(xViewCursor);
    auto xText = xViewCursor->getText();
    CPPUNIT_ASSERT(xText);
    // Create a text cursor from the text view cursor, and move it to the end of the paragraph
    auto xTextCursor = xText->createTextCursorByRange(xViewCursor);
    CPPUNIT_ASSERT(xTextCursor);
    xTextCursor->gotoEnd(false);
    // Get the first paragraph portion from the text cursor
    auto xParaEnum = xTextCursor.queryThrow<container::XEnumerationAccess>()->createEnumeration();
    CPPUNIT_ASSERT(xParaEnum);
    auto xPara = xParaEnum->nextElement().queryThrow<container::XEnumerationAccess>();
    // Try to enumerate text portions. Without the fix, it would fail an assertion in debug builds,
    // and hang in release builds, because the paragraph portion started after the bookmark, and
    // so the bookmark wasn't processed (expectedly):
    auto xRunEnum = xPara->createEnumeration();
    CPPUNIT_ASSERT(!xRunEnum->hasMoreElements()); // Empty enumeration for empty selection
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 709d79e..9177765 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -608,7 +608,9 @@ static void lcl_ExportBookmark(
        const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter;
        if ( nIndex > pPtr->getIndex() )
        {
            assert(!"Some bookmarks were not consumed earlier");
            // We may get here, if SwXTextPortionEnumeration ctor was called with nStart greater
            // than this bookmark's index. Just drop it.
            aIter = rBkmArr.erase(aIter);
            continue;
        }
        if ( nIndex < pPtr->getIndex() )