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>
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 0d87047..edee857 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -1247,6 +1247,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
}
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 220834c..6bfebf8 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -604,7 +604,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() )