summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2020-11-24 20:55:27 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2020-11-25 13:49:28 +0100
commitc1fa005db7a75f54b6651c85ecf897c5857e61f3 (patch)
treeda545818d55e59af1b2fdb23df50582fba5c826c
parentcrashtesting: null deref on load of ooo72915-2.odt (diff)
downloadcore-c1fa005db7a75f54b6651c85ecf897c5857e61f3.tar.gz
core-c1fa005db7a75f54b6651c85ecf897c5857e61f3.zip
fastparser in XMLTextListItemContext
Change-Id: I08f7bc47e7c2e4e7d587d4c766eb2bba6c610adf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106552 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r--xmloff/source/text/XMLTextListBlockContext.cxx179
-rw-r--r--xmloff/source/text/XMLTextListBlockContext.hxx5
-rw-r--r--xmloff/source/text/XMLTextListItemContext.cxx28
-rw-r--r--xmloff/source/text/XMLTextListItemContext.hxx6
4 files changed, 199 insertions, 19 deletions
diff --git a/xmloff/source/text/XMLTextListBlockContext.cxx b/xmloff/source/text/XMLTextListBlockContext.cxx
index 57065a923a0c..71eb988a9e24 100644
--- a/xmloff/source/text/XMLTextListBlockContext.cxx
+++ b/xmloff/source/text/XMLTextListBlockContext.cxx
@@ -43,6 +43,185 @@ using namespace ::xmloff::token;
XMLTextListBlockContext::XMLTextListBlockContext(
SvXMLImport& rImport,
XMLTextImportHelper& rTxtImp,
+ const Reference< xml::sax::XFastAttributeList > & xAttrList,
+ const bool bRestartNumberingAtSubList )
+: SvXMLImportContext( rImport )
+, mrTxtImport( rTxtImp )
+, msListStyleName()
+, mxParentListBlock( )
+, mnLevel( 0 )
+, mbRestartNumbering( false )
+, mbSetDefaults( false )
+, msListId()
+, msContinueListId()
+{
+ static const char s_PropNameDefaultListId[] = "DefaultListId";
+ {
+ // get the parent list block context (if any); this is a bit ugly...
+ XMLTextListBlockContext * pLB(nullptr);
+ XMLTextListItemContext * pLI(nullptr);
+ XMLNumberedParaContext * pNP(nullptr);
+ rTxtImp.GetTextListHelper().ListContextTop(pLB, pLI, pNP);
+ mxParentListBlock = pLB;
+ }
+ // Inherit style name from parent list, as well as the flags whether
+ // numbering must be restarted and formats have to be created.
+ OUString sParentListStyleName;
+ if( mxParentListBlock.is() )
+ {
+ XMLTextListBlockContext *pParent = mxParentListBlock.get();
+ msListStyleName = pParent->msListStyleName;
+ sParentListStyleName = msListStyleName;
+ mxNumRules = pParent->GetNumRules();
+ mnLevel = pParent->GetLevel() + 1;
+ mbRestartNumbering = pParent->IsRestartNumbering() ||
+ bRestartNumberingAtSubList;
+ mbSetDefaults = pParent->mbSetDefaults;
+ msListId = pParent->GetListId();
+ msContinueListId = pParent->GetContinueListId();
+ }
+
+ bool bIsContinueNumberingAttributePresent( false );
+ for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
+ {
+ OUString sValue = aIter.toString();
+ switch( aIter.getToken() )
+ {
+ case XML_ELEMENT(XML, XML_ID):
+//FIXME: there is no UNO API for lists
+ // xml:id is also the list ID (#i92221#)
+ if ( mnLevel == 0 ) // root <list> element
+ {
+ msListId = sValue;
+ }
+ break;
+ case XML_ELEMENT(TEXT, XML_CONTINUE_NUMBERING):
+ mbRestartNumbering = !IsXMLToken(sValue, XML_TRUE);
+ bIsContinueNumberingAttributePresent = true;
+ break;
+ case XML_ELEMENT(TEXT, XML_STYLE_NAME):
+ msListStyleName = sValue;
+ break;
+ case XML_ELEMENT(TEXT, XML_CONTINUE_LIST):
+ if ( mnLevel == 0 ) // root <list> element
+ {
+ msContinueListId = sValue;
+ }
+ break;
+ default:
+ XMLOFF_WARN_UNKNOWN("xmloff", aIter);
+ }
+ }
+
+ // Remember this list block.
+ mrTxtImport.GetTextListHelper().PushListContext( this );
+
+ mxNumRules = XMLTextListsHelper::MakeNumRule(GetImport(), mxNumRules,
+ sParentListStyleName, msListStyleName,
+ mnLevel, &mbRestartNumbering, &mbSetDefaults );
+ if( !mxNumRules.is() )
+ return;
+
+ if ( mnLevel != 0 ) // root <list> element
+ return;
+
+ XMLTextListsHelper& rTextListsHelper( mrTxtImport.GetTextListHelper() );
+ // Inconsistent behavior regarding lists (#i92811#)
+ OUString sListStyleDefaultListId;
+ {
+ uno::Reference< beans::XPropertySet > xNumRuleProps( mxNumRules, UNO_QUERY );
+ if ( xNumRuleProps.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xNumRulePropSetInfo(
+ xNumRuleProps->getPropertySetInfo());
+ if (xNumRulePropSetInfo.is() &&
+ xNumRulePropSetInfo->hasPropertyByName(
+ s_PropNameDefaultListId))
+ {
+ xNumRuleProps->getPropertyValue(s_PropNameDefaultListId)
+ >>= sListStyleDefaultListId;
+ SAL_WARN_IF( sListStyleDefaultListId.isEmpty(), "xmloff",
+ "no default list id found at numbering rules instance. Serious defect." );
+ }
+ }
+ }
+ if ( msListId.isEmpty() ) // no text:id property found
+ {
+ sal_Int32 nUPD( 0 );
+ sal_Int32 nBuild( 0 );
+ const bool bBuildIdFound = GetImport().getBuildIds( nUPD, nBuild );
+ if ( rImport.IsTextDocInOOoFileFormat() ||
+ ( bBuildIdFound && nUPD == 680 ) )
+ {
+ /* handling former documents written by OpenOffice.org:
+ use default list id of numbering rules instance, if existing
+ (#i92811#)
+ */
+ if ( !sListStyleDefaultListId.isEmpty() )
+ {
+ msListId = sListStyleDefaultListId;
+ if ( !bIsContinueNumberingAttributePresent &&
+ !mbRestartNumbering &&
+ rTextListsHelper.IsListProcessed( msListId ) )
+ {
+ mbRestartNumbering = true;
+ }
+ }
+ }
+ if ( msListId.isEmpty() )
+ {
+ // generate a new list id for the list
+ msListId = rTextListsHelper.GenerateNewListId();
+ }
+ }
+
+ if ( bIsContinueNumberingAttributePresent && !mbRestartNumbering &&
+ msContinueListId.isEmpty() )
+ {
+ const OUString& Last( rTextListsHelper.GetLastProcessedListId() );
+ if ( rTextListsHelper.GetListStyleOfLastProcessedList() == msListStyleName
+ && Last != msListId )
+ {
+ msContinueListId = Last;
+ }
+ }
+
+ if ( !msContinueListId.isEmpty() )
+ {
+ if ( !rTextListsHelper.IsListProcessed( msContinueListId ) )
+ {
+ msContinueListId.clear();
+ }
+ else
+ {
+ // search continue list chain for master list and
+ // continue the master list.
+ OUString sTmpStr =
+ rTextListsHelper.GetContinueListIdOfProcessedList( msContinueListId );
+ while ( !sTmpStr.isEmpty() )
+ {
+ msContinueListId = sTmpStr;
+
+ sTmpStr =
+ rTextListsHelper.GetContinueListIdOfProcessedList( msContinueListId );
+ }
+ }
+ }
+
+ if ( !rTextListsHelper.IsListProcessed( msListId ) )
+ {
+ // Inconsistent behavior regarding lists (#i92811#)
+ rTextListsHelper.KeepListAsProcessed(
+ msListId, msListStyleName, msContinueListId,
+ sListStyleDefaultListId );
+ }
+}
+
+// OD 2008-05-07 #refactorlists#
+// add optional parameter <bRestartNumberingAtSubList> and its handling
+XMLTextListBlockContext::XMLTextListBlockContext(
+ SvXMLImport& rImport,
+ XMLTextImportHelper& rTxtImp,
sal_uInt16 nPrfx,
const OUString& rLName,
const Reference< xml::sax::XAttributeList > & xAttrList,
diff --git a/xmloff/source/text/XMLTextListBlockContext.hxx b/xmloff/source/text/XMLTextListBlockContext.hxx
index c26ef5a6ccba..7419613d244a 100644
--- a/xmloff/source/text/XMLTextListBlockContext.hxx
+++ b/xmloff/source/text/XMLTextListBlockContext.hxx
@@ -56,6 +56,11 @@ public:
const OUString& rLName,
const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList,
const bool bRestartNumberingAtSubList = false );
+ XMLTextListBlockContext(
+ SvXMLImport& rImport,
+ XMLTextImportHelper& rTxtImp,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList,
+ const bool bRestartNumberingAtSubList = false );
virtual ~XMLTextListBlockContext() override;
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
diff --git a/xmloff/source/text/XMLTextListItemContext.cxx b/xmloff/source/text/XMLTextListItemContext.cxx
index f11744d2de9a..a82e6ec96fc4 100644
--- a/xmloff/source/text/XMLTextListItemContext.cxx
+++ b/xmloff/source/text/XMLTextListItemContext.cxx
@@ -120,35 +120,31 @@ void XMLTextListItemContext::endFastElement(sal_Int32 )
rTxtImport.GetTextListHelper().SetListItem( nullptr );
}
-SvXMLImportContextRef XMLTextListItemContext::CreateChildContext(
- sal_uInt16 nPrefix,
- const OUString& rLocalName,
- const Reference< xml::sax::XAttributeList > & xAttrList )
+css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTextListItemContext::createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
SvXMLImportContext *pContext = nullptr;
- const SvXMLTokenMap& rTokenMap = rTxtImport.GetTextElemTokenMap();
- bool bHeading = false;
- switch( rTokenMap.Get( nPrefix, rLocalName ) )
+ switch( nElement )
{
- case XML_TOK_TEXT_H:
- bHeading = true;
- [[fallthrough]];
- case XML_TOK_TEXT_P:
- pContext = new XMLParaContext( GetImport(),
- nPrefix, rLocalName,
- xAttrList, bHeading );
+ case XML_ELEMENT(TEXT, XML_H):
+ case XML_ELEMENT(TEXT, XML_P):
+ case XML_ELEMENT(LO_EXT, XML_P):
+ pContext = new XMLParaContext( GetImport(), nElement,
+ xAttrList );
if (rTxtImport.IsProgress())
GetImport().GetProgressBarHelper()->Increment();
break;
- case XML_TOK_TEXT_LIST:
+ case XML_ELEMENT(TEXT, XML_LIST):
++mnSubListCount;
pContext = new XMLTextListBlockContext( GetImport(), rTxtImport,
- nPrefix, rLocalName,
xAttrList,
(mnSubListCount > 1) );
break;
+ default:
+ XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
}
return pContext;
diff --git a/xmloff/source/text/XMLTextListItemContext.hxx b/xmloff/source/text/XMLTextListItemContext.hxx
index 40768d2d02e8..9fabdf6a7ce0 100644
--- a/xmloff/source/text/XMLTextListItemContext.hxx
+++ b/xmloff/source/text/XMLTextListItemContext.hxx
@@ -49,9 +49,9 @@ public:
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
- SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
- const OUString& rLocalName,
- const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList ) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
bool HasStartValue() const { return -1 != nStartValue; }
sal_Int16 GetStartValue() const { return nStartValue; }