diff options
author | Noel <noelgrandin@gmail.com> | 2020-10-19 09:36:04 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2020-10-22 09:12:24 +0200 |
commit | 2b946d245eaf4bd40a0091aa5508315fc37c81a0 (patch) | |
tree | 920dfc7985126f30acff2852b079c5faf0d73dba /xmloff | |
parent | 37a8142720b82d7ce6db0c09593de5cab11c51fd (diff) |
XmlFilterAdaptor: use the fastparser API when possible
part of the process of making SvXMLImport fastparser-only
Which uncovered several bugs because I end up stacking fast and
slow parsers, not once, but twice.
Specifically, we have a problem here with default namespaces e.g.
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<semantics><mrow><mstyle mathsize="12pt">
where going from slow- to fast- parser loses this information,
because there is no way to represent this in the fastparser world,
so we end up with nastiness when we transition back to slow-parser,
and then back-again to fast-parser.
So I fixed a couple of places XMLEmbeddedObjectImportContext
and in SvXMLLegacyToFastDocHandler, and then worked around some of
it by introducing an new XImporter2 interface so I could strip out
out one of the slowparser -> fastparser transitions.
Change-Id: I491487b99271898da50dc999d3b9b9c39cbd97fd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104514
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'xmloff')
-rw-r--r-- | xmloff/source/core/XMLEmbeddedObjectImportContext.cxx | 2 | ||||
-rw-r--r-- | xmloff/source/core/xmlimp.cxx | 51 |
2 files changed, 42 insertions, 11 deletions
diff --git a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx index 36bb7e4d8e7e..c238bbf9de4b 100644 --- a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx +++ b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx @@ -260,7 +260,7 @@ void XMLEmbeddedObjectImportContext::StartElement( sal_uInt16 nPos = rNamespaceMap.GetFirstKey(); while( USHRT_MAX != nPos ) { - OUString aAttrName( rNamespaceMap.GetAttrNameByKey( nPos ) ); + OUString aAttrName = "xmlns:" + rNamespaceMap.GetPrefixByKey( nPos ); if( xAttrList->getValueByName( aAttrName ).isEmpty() ) { pAttrList->AddAttribute( aAttrName, diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx index e56448adabd2..5cddf60205e9 100644 --- a/xmloff/source/core/xmlimp.cxx +++ b/xmloff/source/core/xmlimp.cxx @@ -2248,6 +2248,9 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument() void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName, const uno::Reference< xml::sax::XAttributeList >& xAttrList ) { + sal_uInt16 nDefaultNamespace = XML_NAMESPACE_UNKNOWN; + if (!maDefaultNamespaces.empty()) + nDefaultNamespace = maDefaultNamespaces.top(); mrImport->processNSAttributes(xAttrList); OUString aLocalName; sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); @@ -2257,30 +2260,57 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName, sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; for( sal_Int16 i=0; i < nAttrCount; i++ ) { - OUString aLocalAttrName; - OUString aNamespace; const OUString& rAttrName = xAttrList->getNameByIndex( i ); const OUString& rAttrValue = xAttrList->getValueByIndex( i ); - // don't add unknown namespaces to the map - sal_uInt16 const nAttrPrefix = mrImport->mpNamespaceMap->GetKeyByQName( - rAttrName, nullptr, &aLocalAttrName, &aNamespace, SvXMLNamespaceMap::QNameMode::AttrValue); - if( XML_NAMESPACE_XMLNS != nAttrPrefix ) + if (rAttrName == "xmlns") { - auto const nToken = SvXMLImport::getTokenFromName(aLocalAttrName); - if (XML_NAMESPACE_UNKNOWN == nAttrPrefix || nToken == xmloff::XML_TOKEN_INVALID) + sal_uInt16 nNamespaceKey = mrImport->mpNamespaceMap->GetKeyByName(rAttrValue); + if (nNamespaceKey != XML_NAMESPACE_UNKNOWN) { - mxFastAttributes->addUnknown(aNamespace, + nDefaultNamespace = nNamespaceKey; + continue; + } + assert(false && "unknown namespace"); + } + else if (rAttrName.indexOf(":") == -1 && nDefaultNamespace != XML_NAMESPACE_UNKNOWN) + { + auto const nToken = SvXMLImport::getTokenFromName(rAttrName); + if (nToken == xmloff::XML_TOKEN_INVALID) + { + mxFastAttributes->addUnknown(mrImport->mpNamespaceMap->GetNameByKey(nDefaultNamespace), OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8), OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8)); } else { - sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken; + sal_Int32 const nAttr = NAMESPACE_TOKEN(nDefaultNamespace) | nToken; mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr()); } + continue; + } + + OUString aLocalAttrName; + OUString aNamespace; + // don't add unknown namespaces to the map + sal_uInt16 const nAttrPrefix = mrImport->mpNamespaceMap->GetKeyByQName( + rAttrName, nullptr, &aLocalAttrName, &aNamespace, SvXMLNamespaceMap::QNameMode::AttrValue); + if( XML_NAMESPACE_XMLNS == nAttrPrefix ) + continue; // ignore + auto const nToken = SvXMLImport::getTokenFromName(aLocalAttrName); + if (XML_NAMESPACE_UNKNOWN == nAttrPrefix || nToken == xmloff::XML_TOKEN_INVALID) + { + mxFastAttributes->addUnknown(aNamespace, + OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8), + OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8)); + } + else + { + sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken; + mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8).getStr()); } } mrImport->startFastElement( mnElement, mxFastAttributes.get() ); + maDefaultNamespaces.push(nDefaultNamespace); } void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName ) @@ -2289,6 +2319,7 @@ void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName ) sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName ); sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName(aLocalName); mrImport->endFastElement( mnElement ); + maDefaultNamespaces.pop(); } void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars ) |