sw_redlinehide: fix crash in SwTextNode::SplitContentNode()

Bug happens in the "top" branch of SplitContentNode().

SwTextNode::CutImpl() sends several hints to the SwTextFrame so that it
invalidates itself; a SwInsText and a SwDelText most prominently.

The SwInsText won't have an effect because the target node doesn't have
text frames yet, but the SwDelText should be sufficient to update the
text frames' MergedPara and invalidate the text frames.

The MergedPara is re-created by SwTextFrame::RegisterToNode() anyway,
but that *doesn't* invalidate the SwTextFrame.

Then an additional SwDelText is sent, which will *not* invalidate the
SwTextFrame, because its MergedPara is up-to-date so nothing gets
deleted by the hint.

It's unclear why the LockModify() is done here, since CVS initial
import, perhaps it's some premature optimization; try to remove the
manual sending of SwDelText and just let CutImpl() do it.

Also remove an odd assert in UpdateMergedParaForMove() that i don't
understand the reason for now.

Change-Id: Iba7196556f614356dba4def74f039a88f392eb0f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104219
Tested-by: Michael Stahl <michael.stahl@cib.de>
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
This commit is contained in:
Michael Stahl
2020-10-13 19:42:36 +02:00
committed by Michael Stahl
parent 711522390a
commit fefc0dfdce
4 changed files with 109 additions and 26 deletions
+66
View File
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:font-face-decls>
<style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Lohit Devanagari" svg:font-family="&apos;Lohit Devanagari&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Source Han Serif CN" svg:font-family="&apos;Source Han Serif CN&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:default-style style:family="graphic">
<style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
<style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
<style:tab-stops/>
</style:paragraph-properties>
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
</style:default-style>
<style:default-style style:family="paragraph">
<style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
</style:default-style>
<style:default-style style:family="table">
<style:table-properties table:border-model="collapsing"/>
</style:default-style>
<style:default-style style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text"/>
</office:styles>
<office:automatic-styles>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm">
<style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
</style:page-layout-properties>
<style:header-style/>
<style:footer-style/>
</style:page-layout>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="pm1"/>
</office:master-styles>
<office:body>
<office:text>
<text:tracked-changes text:track-changes="false">
<text:changed-region xml:id="ct110725936" text:id="ct110725936">
<text:deletion>
<office:change-info>
<dc:creator>Unknown Author</dc:creator>
<dc:date>2020-10-12T19:26:19</dc:date>
</office:change-info>
</text:deletion>
</text:changed-region>
<text:changed-region xml:id="ct110726576" text:id="ct110726576">
<text:deletion>
<office:change-info>
<dc:creator>Unknown Author</dc:creator>
<dc:date>2020-10-12T19:26:26</dc:date>
</office:change-info>
</text:deletion>
</text:changed-region>
</text:tracked-changes>
<text:p text:style-name="Standard">A<text:change-start text:change-id="ct110725936"/></text:p>
<text:p text:style-name="Standard"><text:change-end text:change-id="ct110725936"/>xxxxxxxxxxxxxxxxxx<text:change-start text:change-id="ct110726576"/>x</text:p>
<text:p text:style-name="Standard">y<text:change-end text:change-id="ct110726576"/>y</text:p>
</office:text>
</office:body>
</office:document>
+42
View File
@@ -305,6 +305,48 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineInHiddenSection)
CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 4]->IsEndNode());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineSplitContentNode)
{
load(DATA_DIRECTORY, "try2.fodt");
SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
SwWrtShell* const pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
// these are required so that IsBlank() is true
aViewOptions.SetBlank(true);
aViewOptions.SetViewMetaChars(true);
pWrtShell->ApplyViewOptions(aViewOptions);
// enable redlining
dispatchCommand(mxComponent, ".uno:TrackChanges", {});
// hide
dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
SwDocShell* const pDocShell = pTextDoc->GetDocShell();
SwDoc* const pDoc = pDocShell->GetDoc();
CPPUNIT_ASSERT_MESSAGE("redlining should be on",
pDoc->getIDocumentRedlineAccess().IsRedlineOn());
CPPUNIT_ASSERT_MESSAGE(
"redlines should be visible",
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
pWrtShell->CalcLayout();
pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 18, /*bBasicCall=*/false);
pWrtShell->SplitNode(true);
rUndoManager.Undo();
// crashed
pWrtShell->SplitNode(true);
rUndoManager.Undo();
rUndoManager.Redo();
rUndoManager.Undo();
rUndoManager.Redo();
rUndoManager.Undo();
pWrtShell->SplitNode(true);
rUndoManager.Undo();
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132236)
{
load(DATA_DIRECTORY, "tdf132236.odt");
-1
View File
@@ -1906,7 +1906,6 @@ void UpdateMergedParaForMove(sw::MergedPara & rMerged,
}
if (nLastEnd != rNode.Len()) // without nLen, string yet to be removed
{
assert(rNode.Len() == 0 || nLastEnd < nSourceEnd);
if (nLastEnd < nSourceEnd)
{
deleted.emplace_back(std::max(nLastEnd, nSourceStart), nSourceEnd);
+1 -25
View File
@@ -447,9 +447,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
{
// optimization for SplitNode: If a split is at the end of a node then
// move the frames from the current to the new one and create new ones
// for the current one. As a result, no need for recreating the layout.
LockModify(); // disable notifications
// for the current one.
// If fly frames are moved, they don't need to destroy their layout
// frames. Set a flag that is checked in SwTextFlyCnt::SetAnchor.
@@ -557,28 +555,6 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
SetInCache( false );
}
UnlockModify(); // enable notify again
// If there is an accessible layout we must call modify even
// with length zero, because we have to notify about the changed
// text node.
const SwRootFrame *pRootFrame;
if ( (nTextLen != nSplitPos) ||
( (pRootFrame = pNode->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout()) != nullptr &&
pRootFrame->IsAnyShellAccessible() ) )
{
// tell the frames that something was "deleted" at the end
if( 1 == nTextLen - nSplitPos )
{
SwDelChr aHint( nSplitPos );
pNode->NotifyClients( nullptr, &aHint );
}
else
{
SwDelText aHint( nSplitPos, nTextLen - nSplitPos );
pNode->NotifyClients( nullptr, &aHint );
}
}
if ( HasHints() )
{
MoveTextAttr_To_AttrSet();