ofz#20455 sw: HTML import: fix invalid table in footer

The obvious problem was that a bookmark failed to be copied to the
correct node, it was created on a SwStartNode, which failed in
makeMark() and caused a null-pointer.

The target position was off by 1 node because there was a spurious
StartNode/EndNode pair directly below the table:

[  41]   0x5b13430          TableNode ,
[  42]    0x5b1d010         StartNode ,
[  43]     0x5b12a50        StartNode ,
[  44]      0x5b135f0        TextNode "",

This was created by a special case in SwTableNode::MakeCopy() because
.GetTabSortBoxes().size() == 1.

But the table had actually quite a bunch more cells in the nodes-array,
just they were not yet in the SwTable.

In an exciting twist of events, it turns out the table was copied while
it was not yet finished parsing: the problem was that in the middle of
the table, some CSS set some page attributes, and this caused a
first-page page style to be created in SwCSS1Parser::ParseStyleSheet(),
by copying the master page style.

Unfortunately the table was in the <div title="footer">, so it was
copied in this incomplete and inconsistent state.

It might be possible to get rid of the special case in
SwTableNode::MakeCopy() by restricting the special case skipping of
StartNodes at the start in SwNodes::CopyNodes() a bit so that StartNodes
whose EndNodes are copied aren't skipped; at least that's the most
reasonable explanation for the special case.

But for now just fix the HTML import.

Additionally, only on MacOSX, using libc++, this triggered an assert:
  Assertion failed: (!pImpl->mpStaticDefaults || typeid(rItem) == typeid(GetDefaultItem(nWhich))), function PutImpl, file /Users/tdf/lode/jenkins/workspace/lo_gerrit/Config/macosx_clang_dbgutil/svl/source/items/itempool.cxx, line 611.

Probably because SdrTextAniCountItem is not marked DLLPUBLIC.

Change-Id: Ia167265e7540eea649801eaac2b89f9e18b685cd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87859
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
This commit is contained in:
Caolán McNamara
2020-02-03 12:06:23 +00:00
committed by Michael Stahl
parent a9ba8e57a4
commit 086e431480
6 changed files with 21 additions and 8 deletions

View File

@@ -23,7 +23,7 @@
#include <svx/svddef.hxx> #include <svx/svddef.hxx>
// Number of loops. 0=infinite. // Number of loops. 0=infinite.
class SdrTextAniCountItem final : public SfxUInt16Item { class SAL_DLLPUBLIC_RTTI SdrTextAniCountItem final : public SfxUInt16Item {
public: public:
SdrTextAniCountItem(sal_uInt16 nVal=0): SfxUInt16Item(SDRATTR_TEXT_ANICOUNT,nVal) {} SdrTextAniCountItem(sal_uInt16 nVal=0): SfxUInt16Item(SDRATTR_TEXT_ANICOUNT,nVal) {}

Binary file not shown.

View File

@@ -87,11 +87,13 @@ void SwCSS1Parser::ChgPageDesc( const SwPageDesc *pPageDesc,
m_pDoc->ChgPageDesc( pos, rNewPageDesc ); m_pDoc->ChgPageDesc( pos, rNewPageDesc );
} }
SwCSS1Parser::SwCSS1Parser( SwDoc *pD, const sal_uInt32 aFHeights[7], const OUString& rBaseURL, bool bNewDoc ) : SwCSS1Parser::SwCSS1Parser(SwDoc *const pDoc, SwHTMLParser const& rParser,
SvxCSS1Parser( pD->GetAttrPool(), rBaseURL, const sal_uInt32 aFHeights[7], const OUString& rBaseURL, bool const bNewDoc)
aItemIds, SAL_N_ELEMENTS(aItemIds)), : SvxCSS1Parser(pDoc->GetAttrPool(), rBaseURL,
m_pDoc( pD ), aItemIds, SAL_N_ELEMENTS(aItemIds))
m_nDropCapCnt( 0 ), , m_pDoc( pDoc )
, m_rHTMLParser(rParser)
, m_nDropCapCnt( 0 ),
m_bIsNewDoc( bNewDoc ), m_bIsNewDoc( bNewDoc ),
m_bBodyBGColorSet( false ), m_bBodyBGColorSet( false ),
m_bBodyBackgroundSet( false ), m_bBodyBackgroundSet( false ),
@@ -1341,6 +1343,12 @@ const SwPageDesc *SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId, bool bCreate )
const SwPageDesc *pPageDesc = FindPageDesc(m_pDoc, nPoolId); const SwPageDesc *pPageDesc = FindPageDesc(m_pDoc, nPoolId);
if( !pPageDesc && bCreate ) if( !pPageDesc && bCreate )
{ {
if (m_rHTMLParser.IsReadingHeaderOrFooter())
{ // (there should be only one definition of header/footer in HTML)
SAL_WARN("sw.html", "no creating PageDesc while reading header/footer");
return nullptr;
}
// The first page is created from the right page, if there is one. // The first page is created from the right page, if there is one.
SwPageDesc *pMasterPageDesc = nullptr; SwPageDesc *pMasterPageDesc = nullptr;
if( RES_POOLPAGE_FIRST == nPoolId ) if( RES_POOLPAGE_FIRST == nPoolId )

View File

@@ -33,6 +33,7 @@ class SwTextFormatColl;
class SvxBrushItem; class SvxBrushItem;
class SwFormatDrop; class SwFormatDrop;
class SwPageDesc; class SwPageDesc;
class SwHTMLParser;
// This header looks harmless, but includes still quite // This header looks harmless, but includes still quite
// inconspicuous one or the other! On the other hand this class // inconspicuous one or the other! On the other hand this class
@@ -41,6 +42,7 @@ class SwPageDesc;
class SwCSS1Parser : public SvxCSS1Parser class SwCSS1Parser : public SvxCSS1Parser
{ {
SwDoc *m_pDoc; SwDoc *m_pDoc;
SwHTMLParser const& m_rHTMLParser;
sal_uLong m_aFontHeights[7]; sal_uLong m_aFontHeights[7];
@@ -75,7 +77,8 @@ protected:
using CSS1Parser::ParseStyleSheet; using CSS1Parser::ParseStyleSheet;
public: public:
SwCSS1Parser( SwDoc *pDoc, sal_uInt32 const aFHeight[7], const OUString& rBaseURL, bool bNewDoc ); SwCSS1Parser( SwDoc *pDoc, SwHTMLParser const& rParser,
sal_uInt32 const aFHeight[7], const OUString& rBaseURL, bool bNewDoc);
virtual ~SwCSS1Parser() override; virtual ~SwCSS1Parser() override;
virtual bool ParseStyleSheet( const OUString& rIn ) override; virtual bool ParseStyleSheet( const OUString& rIn ) override;

View File

@@ -358,7 +358,7 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn,
m_bOldIsHTMLMode = m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE); m_bOldIsHTMLMode = m_xDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE);
m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, true); m_xDoc->getIDocumentSettingAccess().set(DocumentSettingId::HTML_MODE, true);
m_pCSS1Parser.reset( new SwCSS1Parser( m_xDoc.get(), m_aFontHeights, m_sBaseURL, IsNewDoc() ) ); m_pCSS1Parser.reset(new SwCSS1Parser(m_xDoc.get(), *this, m_aFontHeights, m_sBaseURL, IsNewDoc()));
m_pCSS1Parser->SetIgnoreFontFamily( rHtmlOptions.IsIgnoreFontFamily() ); m_pCSS1Parser->SetIgnoreFontFamily( rHtmlOptions.IsIgnoreFontFamily() );
if( bReadUTF8 ) if( bReadUTF8 )

View File

@@ -924,6 +924,8 @@ public:
bool IsReqIF() const; bool IsReqIF() const;
bool IsReadingHeaderOrFooter() const { return m_bReadingHeaderOrFooter; }
void NotifyMacroEventRead(); void NotifyMacroEventRead();
/// Strips query and fragment from a URL path if base URL is a file:// one. /// Strips query and fragment from a URL path if base URL is a file:// one.