From 80fd9fb7209cfd5c0622ee99d59e42e6db32f021 Mon Sep 17 00:00:00 2001 From: Umesh Kadam Date: Thu, 15 May 2014 23:02:34 +0530 Subject: [PATCH] fdo#78333 : SdtContent and a Shape overlapping causes corruption - Normally if there is a case where text/shape is overlapped with (another) shape then LO used to write the text and the AlternateContent in the same run. - This is supported in MSO and there is no visual difference. - But in case if the SdtContent(with text) is overlapped with the Shape then LO processes sdtContent as a text and ends up putting the alternateContent and the text in a single run. Ultimately it includes the entire run in a SdtContent, which is incorrect. - The fix checks for the aforementioned scenario and puts them in a different run and also restricts the sdtContent being written in an invalid AlternateContent. Change-Id: I36f4cdb1b583523dd8f717ae094bdf09c7a61f62 Reviewed-on: https://gerrit.libreoffice.org/9374 Reviewed-by: Miklos Vajna Tested-by: Miklos Vajna --- .../data/ShapeOverlappingWithSdt.docx | Bin 0 -> 29760 bytes sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 9 ++ sw/source/filter/ww8/attributeoutputbase.hxx | 9 ++ sw/source/filter/ww8/docxattributeoutput.cxx | 69 +++++++++++++++- sw/source/filter/ww8/docxattributeoutput.hxx | 6 ++ sw/source/filter/ww8/wrtw8nds.cxx | 78 ++++++++++++++++-- sw/source/filter/ww8/wrtww8.hxx | 13 ++- 7 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/ShapeOverlappingWithSdt.docx diff --git a/sw/qa/extras/ooxmlexport/data/ShapeOverlappingWithSdt.docx b/sw/qa/extras/ooxmlexport/data/ShapeOverlappingWithSdt.docx new file mode 100644 index 0000000000000000000000000000000000000000..e1ec07489e666fb64c5d314194d84419c55f27e9 GIT binary patch literal 29760 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 eQJrO z{q|6+jS3|o#0|~727v9}vNkFR?;(Nh02tk1W1lSEL<$$J+ z>x0igm@D8=&#_XwDZjC!eWg-7d|%J}mdsjJL4nwX*L$+W`!--hp@7J-1| zwY6OU<`&ABJaKM(D8L7sQ+idOIGrCV{2*ht9(og|F6Cy zvy6*4r%+S(rfh*FeS}R^xx7#kdxI4njz7ETuh$6`zM&9`?-!w4)!75r4zt+hv@2jL zMFdt8VTk20gKy~C`<3^hVmzc$;b*Lz#sSeZQkPD1HJyhSyaX-=umw?M1~RTjF`d+H$ExrQdPBr%0W79 zuPG?=eGgxyON#7{$o8%KJnEiS+4KFn>&EPKL>9$gAK)r9t&BG#Rf68}4*~}}E3>XK z*%h(bs3etdEzRglM72P~V}AxRzC*DJaOK(D<8+Aiw*Xg*tZxH?EJF~Wsiw>i%mWWO zvul(xG|kI(+*XFzL+)k$lj{uexKgPbdo_0){l4i~Zt

IJl$QpJyqCpp>AieUz@e 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 I{p0HY0D^H$n*aa+ literal 0 HcmV?d00001 diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 7a69e6769e5f..16d13a2e90a8 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2052,6 +2052,15 @@ DECLARE_OOXMLEXPORT_TEST(testFileOpenInputOutputError,"floatingtbl_with_formula. assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:pStyle", "val", "Normal"); } +DECLARE_OOXMLEXPORT_TEST(testSdtAndShapeOverlapping,"ShapeOverlappingWithSdt.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + if (!pXmlDoc) + return; + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r[1]/mc:AlternateContent"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt[1]/w:sdtContent[1]/w:r[1]/w:t[1]"); +} + DECLARE_OOXMLEXPORT_TEST(testRelorientation, "relorientation.docx") { uno::Reference xShape = getShape(1); diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index 5a25c86a5fe4..d2df9c08be8c 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -309,6 +309,15 @@ public: /// Has different headers/footers for the title page. virtual void SectionTitlePage() = 0; + /// If the node has an anchor linked. + virtual void SetAnchorIsLinkedToNode( bool /*bAnchorLinkedToNode*/){}; + + /// Is processing of fly postponed ? + virtual bool IsFlyProcessingPostponed(){ return false; }; + + /// Reset the flag for FlyProcessing + virtual void ResetFlyProcessingFlag(){}; + /// Description of the page borders. virtual void SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* pFirstPageFmt ) = 0; diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 96602c3ff468..fb5933dd72f3 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -287,6 +287,20 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText m_bIsFirstParagraph = false; } +static void lcl_deleteAndResetTheLists( ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs) +{ + if( pSdtPrTokenChildren ) + { + delete pSdtPrTokenChildren ; + pSdtPrTokenChildren = NULL; + } + if( pSdtPrDataBindingAttrs ) + { + delete pSdtPrDataBindingAttrs; + pSdtPrDataBindingAttrs = NULL; + } +} + void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) { // write the paragraph properties + the run, already in the correct order @@ -382,8 +396,16 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT } m_pSerializer->endElementNS( XML_w, XML_p ); + if( !m_bAnchorLinkedToNode ) + WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs ); + else + { + //These should be written out to the actual Node and not to the anchor. + //Clear them as they will be repopulated when the node is processed. + m_nParagraphSdtPrToken = 0; + lcl_deleteAndResetTheLists( m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs ); + } - WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs ); //sdtcontent is written so Set m_bParagraphHasDrawing to false m_rExport.SdrExporter().setParagraphHasDrawing( false ); m_bRunTextIsOn = false; @@ -701,6 +723,21 @@ void DocxAttributeOutput::EndParagraphProperties( const SfxItemSet* pParagraphMa m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND ); } +void DocxAttributeOutput::SetAnchorIsLinkedToNode( bool bAnchorLinkedToNode ) +{ + m_bAnchorLinkedToNode = bAnchorLinkedToNode ; +} + +void DocxAttributeOutput::ResetFlyProcessingFlag() +{ + m_bPostponedProcessingFly = false ; +} + +bool DocxAttributeOutput::IsFlyProcessingPostponed() +{ + return m_bPostponedProcessingFly; +} + void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bSingleEmptyRun*/ ) { // Don't start redline data here, possibly there is a hyperlink later, and @@ -858,7 +895,15 @@ void DocxAttributeOutput::EndRun() EndRedline( m_pRedlineData ); // enclose in a sdt block, if necessary - WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs ); + if ( !m_bAnchorLinkedToNode ) + WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs ); + else + { + //These should be written out to the actual Node and not to the anchor. + //Clear them as they will be repopulated when the node is processed. + m_nRunSdtPrToken = 0; + lcl_deleteAndResetTheLists( m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs ); + } m_pSerializer->mergeTopMarks(); WritePostponedMath(); @@ -4270,9 +4315,13 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po if ( pGrfNode ) { if( m_postponedGraphic == NULL ) + { + m_bPostponedProcessingFly = false ; FlyFrameGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj); + } else // we are writing out attributes, but w:drawing should not be inside w:rPr, { // so write it out later + m_bPostponedProcessingFly = true ; m_postponedGraphic->push_back( PostponedGraphic( pGrfNode, rFrame.GetLayoutSize(), 0, 0, pSdrObj)); } } @@ -4286,9 +4335,13 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po if ( IsDiagram( pSdrObj ) ) { if ( m_postponedDiagram == NULL ) + { + m_bPostponedProcessingFly = false ; m_rExport.SdrExporter().writeDiagram( pSdrObj, rFrame.GetFrmFmt(), m_anchorId++); + } else // we are writing out attributes, but w:drawing should not be inside w:rPr, { // so write it out later + m_bPostponedProcessingFly = true ; m_postponedDiagram->push_back( PostponedDiagram( pSdrObj, &(rFrame.GetFrmFmt()) )); } } @@ -4302,6 +4355,8 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po m_rExport.SdrExporter().writeDMLDrawing( pSdrObj, &rFrame.GetFrmFmt(), m_anchorId++); else m_rExport.SdrExporter().writeDMLAndVMLDrawing( pSdrObj, rFrame.GetFrmFmt(), rNdTopLeft, m_anchorId++); + + m_bPostponedProcessingFly = false ; } // IsAlternateContentChoiceOpen() : check is to ensure that only one object is getting added. Without this check, plus one obejct gets added // m_bParagraphFrameOpen : Check if the frame is open. @@ -4311,8 +4366,11 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po m_postponedCustomShape->push_back(PostponedDrawing(pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft)); } else + { // we are writing out attributes, but w:drawing should not be inside w:rPr, so write it out later + m_bPostponedProcessingFly = true ; m_postponedDMLDrawing->push_back(PostponedDrawing(pSdrObj, &(rFrame.GetFrmFmt()), &rNdTopLeft)); + } } } } @@ -4335,7 +4393,10 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po } if( !bDuplicate ) + { + m_bPostponedProcessingFly = true ; m_aFramesOfParagraph.push_back(sw::Frame(rFrame)); + } } break; case sw::Frame::eOle: @@ -4347,6 +4408,7 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1); SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode(); WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize(), dynamic_cast( &rFrmFmt )); + m_bPostponedProcessingFly = false ; } } break; @@ -4354,6 +4416,7 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po { const SdrObject* pObject = rFrame.GetFrmFmt().FindRealSdrObject(); m_aPostponedFormControls.push_back(pObject); + m_bPostponedProcessingFly = true ; } break; default: @@ -7432,6 +7495,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri m_bOpenedSectPr( false ), m_bRunTextIsOn( false ), m_bWritingHeaderFooter( false ), + m_bAnchorLinkedToNode(false), m_sFieldBkm( ), m_nNextBookmarkId( 0 ), m_nNextAnnotationMarkId( 0 ), @@ -7440,6 +7504,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri m_bParagraphFrameOpen( false ), m_bIsFirstParagraph( true ), m_bAlternateContentChoiceOpen( false ), + m_bPostponedProcessingFly( false ), m_nColBreakStatus( COLBRK_NONE ), m_nTextFrameLevel( 0 ), m_closeHyperlinkInThisRun( false ), diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 2c0472d5cab6..ea609a67aad7 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -210,6 +210,10 @@ public: /// End of the tag that encloses the run. void EndRedline( const SwRedlineData * pRedlineData ); + virtual void SetAnchorIsLinkedToNode( bool bAnchorLinkedToNode = false ) SAL_OVERRIDE; + virtual bool IsFlyProcessingPostponed() SAL_OVERRIDE; + virtual void ResetFlyProcessingFlag() SAL_OVERRIDE; + virtual void FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) SAL_OVERRIDE; /// Output style. @@ -726,6 +730,7 @@ private: /// Flag indicating that the header \ footer are being written bool m_bWritingHeaderFooter; + bool m_bAnchorLinkedToNode; /// Field data to remember in the text run std::vector< FieldInfos > m_Fields; @@ -767,6 +772,7 @@ private: bool m_bParagraphFrameOpen; bool m_bIsFirstParagraph; bool m_bAlternateContentChoiceOpen; + bool m_bPostponedProcessingFly; // Remember that a column break has to be opened at the // beginning of the next paragraph diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 16019979d2d2..e17625969a2e 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -540,7 +540,26 @@ bool SwWW8AttrIter::IsWatermarkFrame() return false; } -void SwWW8AttrIter::OutFlys(sal_Int32 nSwPos) +bool SwWW8AttrIter::IsAnchorLinkedToThisNode( sal_uLong nNodePos ) +{ + sw::FrameIter aTmpFlyIter = maFlyIter ; + + while ( aTmpFlyIter != maFlyFrms.end() ) + { + const SwPosition &rAnchor = maFlyIter->GetPosition(); + sal_uLong nAnchorPos = rAnchor.nNode.GetIndex(); + /* if current node position and the anchor position are the same + then the frame anchor is linked to this node + */ + if ( nAnchorPos == nNodePos ) + return true ; + + ++aTmpFlyIter; + } + return false ; +} + +sal_Int16 SwWW8AttrIter::OutFlys(sal_Int32 nSwPos) { /* #i2916# @@ -553,7 +572,7 @@ void SwWW8AttrIter::OutFlys(sal_Int32 nSwPos) const sal_Int32 nPos = rAnchor.nContent.GetIndex(); if ( nPos != nSwPos ) - break; + return FLY_NOT_PROCESSED ; //We havent processed the fly const SdrObject* pSdrObj = maFlyIter->GetFrmFmt().FindRealSdrObject(); @@ -585,6 +604,7 @@ void SwWW8AttrIter::OutFlys(sal_Int32 nSwPos) } ++maFlyIter; } + return ( m_rExport.AttrOutput().IsFlyProcessingPostponed() ? FLY_POSTPONED : FLY_PROCESSED ) ; } bool SwWW8AttrIter::IsTxtAttr( sal_Int32 nSwPos ) @@ -2017,6 +2037,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) sal_Int32 const nEnd = aStr.getLength(); bool bRedlineAtEnd = false; sal_Int32 nOpenAttrWithRange = 0; + OUString aStringForImage("\001"); ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner; if ( pTextNodeInfo.get() != NULL ) @@ -2024,18 +2045,33 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) do { const SwRedlineData* pRedlineData = aAttrIter.GetRunLevelRedline( nAktPos ); + sal_Int16 nStateOfFlyFrame = 0; + bool bPostponeWritingText = false ; + OUString aSavedSnippet ; sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos ); // Is this the only run in this paragraph and it's empty? bool bSingleEmptyRun = nAktPos == 0 && nNextAttr == 0; AttrOutput().StartRun( pRedlineData, bSingleEmptyRun ); + if( nTxtTyp == TXT_FTN || nTxtTyp == TXT_EDN ) AttrOutput().FootnoteEndnoteRefTag(); if( nNextAttr > nEnd ) nNextAttr = nEnd; - aAttrIter.OutFlys( nAktPos ); + /* + 1) If there is a text node and an overlapping anchor, then write them in two different + runs and not as part of the same run. + 2) Ensure that it is a text node and not in a fly. + 3) If the anchor is associated with a text node with empty text then we ignore. + */ + if ( rNode.IsTxtNode() && aStr != aStringForImage && aStr != "" && + !rNode.GetFlyFmt() && aAttrIter.IsAnchorLinkedToThisNode(rNode.GetIndex())) + bPostponeWritingText = true ; + + nStateOfFlyFrame = aAttrIter.OutFlys( nAktPos ); + AttrOutput().SetAnchorIsLinkedToNode( bPostponeWritingText && (FLY_POSTPONED != nStateOfFlyFrame) ); // Append bookmarks in this range after flys, exclusive of final // position of this range AppendBookmarks( rNode, nAktPos, nNextAttr - nAktPos ); @@ -2152,7 +2188,17 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) if ( aSnippet[0] != 0x09 ) aSnippet = OUString( 0x09 ) + aSnippet; } - AttrOutput().RunText( aSnippet, eChrSet ); + + if ( bPostponeWritingText && ( FLY_POSTPONED != nStateOfFlyFrame ) ) + { + bPostponeWritingText = true ; + aSavedSnippet = aSnippet ; + } + else + { + bPostponeWritingText = false ; + AttrOutput().RunText( aSnippet, eChrSet ); + } } if ( aAttrIter.IsDropCap( nNextAttr ) ) @@ -2179,7 +2225,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) else { // insert final graphic anchors if any before CR - aAttrIter.OutFlys( nEnd ); + nStateOfFlyFrame = aAttrIter.OutFlys( nEnd ); // insert final bookmarks if any before CR and after flys AppendBookmarks( rNode, nEnd, 1 ); AppendAnnotationMarks( rNode, nEnd, 1 ); @@ -2228,7 +2274,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) if ( bTxtAtr || bAttrWithRange || bRedlineAtEnd ) { // insert final graphic anchors if any before CR - aAttrIter.OutFlys( nEnd ); + nStateOfFlyFrame = aAttrIter.OutFlys( nEnd ); // insert final bookmarks if any before CR and after flys AppendBookmarks( rNode, nEnd, 1 ); AppendAnnotationMarks( rNode, nEnd, 1 ); @@ -2256,7 +2302,25 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) AttrOutput().WritePostitFieldReference(); - AttrOutput().EndRun(); + if( bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame ) + { + AttrOutput().EndRun(); + //write the postponed text run + bPostponeWritingText = false ; + AttrOutput().StartRun( pRedlineData, bSingleEmptyRun ); + AttrOutput().SetAnchorIsLinkedToNode( false ); + AttrOutput().ResetFlyProcessingFlag(); + if (0 != nEnd) + { + AttrOutput().StartRunProperties(); + aAttrIter.OutAttr( nAktPos ); + AttrOutput().EndRunProperties( pRedlineData ); + } + AttrOutput().RunText( aSavedSnippet, eChrSet ); + AttrOutput().EndRun(); + } + else + AttrOutput().EndRun(); nAktPos = nNextAttr; UpdatePosition( &aAttrIter, nAktPos, nEnd ); diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 9229fa5fcc71..36b260f21029 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -145,6 +145,16 @@ enum TxtTypes //enums for TextTypes TXT_EDN = 4, TXT_ATN = 5, TXT_TXTBOX = 6, TXT_HFTXTBOX= 7 }; +/** +enum to state the present state of the fly +*/ +enum FlyProcessingState +{ + FLY_PROCESSED, + FLY_POSTPONED, + FLY_NOT_PROCESSED +}; + struct WW8_SepInfo { const SwPageDesc* pPageDesc; @@ -1533,7 +1543,7 @@ public: int OutAttrWithRange(sal_Int32 nPos); const SwRedlineData* GetParagraphLevelRedline( ); const SwRedlineData* GetRunLevelRedline( sal_Int32 nPos ); - void OutFlys(sal_Int32 nSwPos); + sal_Int16 OutFlys(sal_Int32 nSwPos); sal_Int32 WhereNext() const { return nAktSwPos; } sal_uInt16 GetScript() const { return mnScript; } @@ -1545,6 +1555,7 @@ public: const SwFmtDrop& GetSwFmtDrop() const { return mrSwFmtDrop; } bool IsWatermarkFrame(); + bool IsAnchorLinkedToThisNode( sal_uLong nNodePos ); }; /// Class to collect and output the styles table.