summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-01-19 11:11:43 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-01-19 12:19:13 +0000
commit1b6fa616087e7415be9dc7113bbd8bf381aadd70 (patch)
tree56b6734afa99a07c8f0a861492914a5e512041ec
parent968f6a7f0293c08a73807603f3cb294e4b50bad8 (diff)
tdf#105417 sw hyphenation: avoid infinite loop on zero-length last line
This hang happened when the user executed Tools -> Language -> Hyphenation -> Hyphenate All. This problem is visible only if all of these conditions are met: - a line in a paragraph has a word that already contains a soft-hyphen, but not at the position where the automatic hyphenation would insert it - the last line ends with a word that can be hyphenated - there is a fly frame in the document In this case it happens during hyphenation that the layout has an additional empty line at the end (which is removed by the time the layout finishes), so we hit the case when SwTextFormatter::Hyphenate() skips the "if( m_pCurr->PrtWidth() && m_pCurr->GetLen() )" block. Normally hyphenation terminates when it iterates over the portions of the line and no overrun nor any existing hyphen portion are seen, but in this case that never happened. Fix the problem by terminating not only when we reach the end of the portion iteration, but also when the portion list is non-existing (has zero length). Change-Id: I71d4b040a2d4692ae6eb92807dbbbb42b077a0f8 Reviewed-on: https://gerrit.libreoffice.org/33303 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r--sw/qa/extras/uiwriter/data/tdf105417.odtbin0 -> 9238 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx27
-rw-r--r--sw/source/core/text/txthyph.cxx5
-rw-r--r--sw/source/uibase/inc/hyp.hxx3
-rw-r--r--sw/source/uibase/lingu/hyp.cxx2
5 files changed, 35 insertions, 2 deletions
diff --git a/sw/qa/extras/uiwriter/data/tdf105417.odt b/sw/qa/extras/uiwriter/data/tdf105417.odt
new file mode 100644
index 000000000000..d594d2a5aed5
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf105417.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index f984499decfd..e879cd22ee86 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -88,6 +88,7 @@
#include <paratr.hxx>
#include <drawfont.hxx>
#include <txtfrm.hxx>
+#include <hyp.hxx>
#include <editeng/svxenum.hxx>
#include <comphelper/propertysequence.hxx>
#include <sfx2/classificationhelper.hxx>
@@ -96,6 +97,7 @@
#include <sfx2/dispatch.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/configurationhelper.hxx>
+#include <editeng/unolingu.hxx>
#include <config_features.h>
static const char* const DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/";
@@ -222,6 +224,7 @@ public:
void testTdf104814();
void testTdf66405();
void testTdf104492();
+ void testTdf105417();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
@@ -340,6 +343,7 @@ public:
CPPUNIT_TEST(testTdf104814);
CPPUNIT_TEST(testTdf66405);
CPPUNIT_TEST(testTdf104492);
+ CPPUNIT_TEST(testTdf105417);
CPPUNIT_TEST_SUITE_END();
private:
@@ -4211,6 +4215,29 @@ void SwUiWriterTest::testTdf104492()
assertXPath(pXmlDoc, "//page", 3);
}
+void SwUiWriterTest::testTdf105417()
+{
+ SwDoc* pDoc = createDoc("tdf105417.odt");
+ CPPUNIT_ASSERT(pDoc);
+ SwView* pView = pDoc->GetDocShell()->GetView();
+ CPPUNIT_ASSERT(pView);
+ uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
+ CPPUNIT_ASSERT(xHyphenator.is());
+ // If there are no English hyphenation rules installed, we can't test
+ // hyphenation.
+ if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
+ return;
+
+ uno::Reference<linguistic2::XLinguProperties> xLinguProperties(LinguMgr::GetLinguPropertySet());
+ // Automatic hyphenation means not opening a dialog, but going ahead
+ // non-interactively.
+ xLinguProperties->setIsHyphAuto(true);
+ SwHyphWrapper aWrap(pView, xHyphenator, /*bStart=*/false, /*bOther=*/true, /*bSelection=*/false);
+ // This never returned, it kept trying to hyphenate the last word
+ // (greenbacks) again and again.
+ aWrap.SpellDocument();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/text/txthyph.cxx b/sw/source/core/text/txthyph.cxx
index 369a22ae3b03..6b5bd8470648 100644
--- a/sw/source/core/text/txthyph.cxx
+++ b/sw/source/core/text/txthyph.cxx
@@ -197,6 +197,11 @@ bool SwTextFormatter::Hyphenate( SwInterHyphInfo &rHyphInf )
if( !pPos )
nWrdStart = 0;
}
+ else
+ // In case the whole line is zero-length, that's the same situation as
+ // above when the portion iteration ends without explicitly breaking
+ // from the loop.
+ nWrdStart = 0;
// Das alte LineLayout wird wieder eingestellt ...
delete m_pCurr;
diff --git a/sw/source/uibase/inc/hyp.hxx b/sw/source/uibase/inc/hyp.hxx
index 24942e31c680..e12638fa6575 100644
--- a/sw/source/uibase/inc/hyp.hxx
+++ b/sw/source/uibase/inc/hyp.hxx
@@ -23,10 +23,11 @@
#include <tools/link.hxx>
#include <editeng/splwrap.hxx>
#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <swdllapi.h>
class SwView;
-class SwHyphWrapper : public SvxSpellWrapper {
+class SW_DLLPUBLIC SwHyphWrapper : public SvxSpellWrapper {
private:
SwView* pView;
sal_uInt16 nPageCount; // page count for progress view
diff --git a/sw/source/uibase/lingu/hyp.cxx b/sw/source/uibase/lingu/hyp.cxx
index 3b2385f80e35..8f96c7fa9481 100644
--- a/sw/source/uibase/lingu/hyp.cxx
+++ b/sw/source/uibase/lingu/hyp.cxx
@@ -118,7 +118,7 @@ SwHyphWrapper::~SwHyphWrapper()
{
if( nPageCount )
::EndProgress( pView->GetDocShell() );
- if( bInfoBox )
+ if( bInfoBox && !Application::IsHeadlessModeEnabled() )
ScopedVclPtrInstance<InfoBox>(&pView->GetEditWin(), SW_RESSTR(STR_HYP_OK))->Execute();
}