1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <optional>
22 
23 #include <tools/diagnose_ex.h>
24 #include <sal/log.hxx>
25 #include <com/sun/star/beans/XPropertySetInfo.hpp>
26 #include <tools/urlobj.hxx>
27 #include <vcl/embeddedfontshelper.hxx>
28 #include <vcl/graph.hxx>
29 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
30 #include <xmloff/namespacemap.hxx>
31 #include <xmloff/xmluconv.hxx>
32 #include <xmloff/xmlnamespace.hxx>
33 #include <xmloff/xmltoken.hxx>
34 #include <xmloff/XMLFontStylesContext.hxx>
35 #include <xmloff/xmlictxt.hxx>
36 #include <xmloff/xmlimp.hxx>
37 #include <xmloff/xmlnumfi.hxx>
38 #include <XMLEventImportHelper.hxx>
39 #include <XMLStarBasicContextFactory.hxx>
40 #include <XMLScriptContextFactory.hxx>
41 #include <StyleMap.hxx>
42 #include <xmloff/ProgressBarHelper.hxx>
43 #include <xmloff/xmlerror.hxx>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
47 #include <com/sun/star/io/XOutputStream.hpp>
48 #include <com/sun/star/util/MeasureUnit.hpp>
49 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
50 #include <com/sun/star/frame/XModel.hpp>
51 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
52 #include <com/sun/star/document/XStorageBasedDocument.hpp>
53 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
54 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
55 #include <com/sun/star/xml/sax/XLocator.hpp>
56 #include <com/sun/star/xml/sax/FastParser.hpp>
57 #include <com/sun/star/xml/sax/SAXException.hpp>
58 #include <com/sun/star/packages/zip/ZipIOException.hpp>
59 #include <comphelper/fileformat.h>
60 #include <comphelper/namecontainer.hxx>
61 #include <comphelper/servicehelper.hxx>
62 #include <cppuhelper/implbase.hxx>
63 #include <cppuhelper/supportsservice.hxx>
64 #include <comphelper/extract.hxx>
65 #include <comphelper/documentconstants.hxx>
66 #include <comphelper/documentinfo.hxx>
67 #include <comphelper/storagehelper.hxx>
68 #include <comphelper/attributelist.hxx>
69 #include <unotools/fontcvt.hxx>
70 #include <fasttokenhandler.hxx>
71 #include <vcl/GraphicExternalLink.hxx>
72 
73 #include <com/sun/star/rdf/XMetadatable.hpp>
74 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
75 #include <RDFaImportHelper.hxx>
76 
77 using ::com::sun::star::beans::XPropertySetInfo;
78 
79 using namespace ::com::sun::star;
80 using namespace ::com::sun::star::uno;
81 using namespace ::com::sun::star::util;
82 using namespace ::com::sun::star::io;
83 using namespace ::com::sun::star::container;
84 using namespace ::com::sun::star::document;
85 using namespace ::xmloff::token;
86 
87 rtl::Reference< FastTokenHandler > SvXMLImport::xTokenHandler( new FastTokenHandler() );
88 std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap;
89 std::unordered_map< OUString, OUString > SvXMLImport::aNamespaceURIPrefixMap;
90 bool SvXMLImport::bIsNSMapsInitialized = false;
91 
92 namespace {
93 
94 class SvXMLImportEventListener : public cppu::WeakImplHelper< css::lang::XEventListener >
95 {
96 private:
97     SvXMLImport*    pImport;
98 
99 public:
100     explicit SvXMLImportEventListener(SvXMLImport* pImport);
101 
102                             // XEventListener
103     virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
104 };
105 
106 }
107 
SvXMLImportEventListener(SvXMLImport * pTempImport)108 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport)
109     : pImport(pTempImport)
110 {
111 }
112 
113 // XEventListener
disposing(const lang::EventObject &)114 void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& )
115 {
116     if (pImport)
117     {
118         pImport->DisposingModel();
119         pImport = nullptr;
120     }
121 }
122 
123 namespace
124 {
125 
126 OUString
getBuildIdsProperty(uno::Reference<beans::XPropertySet> const & xImportInfo)127 getBuildIdsProperty(uno::Reference<beans::XPropertySet> const& xImportInfo)
128 {
129     if (xImportInfo.is())
130     {
131         try
132         {
133             Reference< XPropertySetInfo > const xSetInfo(
134                     xImportInfo->getPropertySetInfo());
135             if (xSetInfo.is() && xSetInfo->hasPropertyByName("BuildId"))
136             {
137                 OUString aBuildId;
138                 xImportInfo->getPropertyValue("BuildId") >>= aBuildId;
139                 return aBuildId;
140             }
141         }
142         catch (Exception const&)
143         {
144             DBG_UNHANDLED_EXCEPTION("xmloff.core", "exception getting BuildId");
145         }
146     }
147     return OUString();
148 }
149 
150 class DocumentInfo
151 {
152 private:
153     sal_uInt16 mnGeneratorVersion;
154 
155 public:
DocumentInfo(const SvXMLImport & rImport)156     explicit DocumentInfo( const SvXMLImport& rImport )
157         : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown )
158     {
159         OUString const buildIds(
160                 getBuildIdsProperty(rImport.getImportInfo()));
161         if (!buildIds.isEmpty())
162         {
163             sal_Int32 const ix = buildIds.indexOf(';');
164             if (-1 != ix)
165             {
166                 OUString const loVersion(buildIds.copy(ix + 1));
167                 if (!loVersion.isEmpty())
168                 {
169                     if ('3' == loVersion[0])
170                     {
171                         mnGeneratorVersion = SvXMLImport::LO_3x;
172                     }
173                     else if ('4' == loVersion[0])
174                     {
175                         if (loVersion.getLength() > 1
176                             && (loVersion[1] == '0' || loVersion[1] == '1'))
177                         {
178                             mnGeneratorVersion = SvXMLImport::LO_41x; // 4.0/4.1
179                         }
180                         else if (loVersion.getLength() > 1 && '2' == loVersion[1])
181                         {
182                             mnGeneratorVersion = SvXMLImport::LO_42x; // 4.2
183                         }
184                         else if (loVersion.getLength() > 1 && '3' == loVersion[1])
185                         {
186                             mnGeneratorVersion = SvXMLImport::LO_43x; // 4.3
187                         }
188                         else if (loVersion.getLength() > 1 && '4' == loVersion[1])
189                         {
190                             mnGeneratorVersion = SvXMLImport::LO_44x; // 4.4
191                         }
192                     }
193                     else if ('5' == loVersion[0])
194                     {
195                         mnGeneratorVersion = SvXMLImport::LO_5x;
196                     }
197                     else if ('6' == loVersion[0])
198                     {
199                         if (loVersion.getLength() > 1
200                             && (loVersion[1] == '0' || loVersion[1] == '1'
201                                 || loVersion[1] == '2'))
202                         {
203                             mnGeneratorVersion = SvXMLImport::LO_6x; // 6.0/6.1/6.2
204                         }
205                         else
206                         {
207                             mnGeneratorVersion = SvXMLImport::LO_63x; // 6.3/6.4
208                         }
209                     }
210                     else if ('7' == loVersion[0])
211                     {
212                         mnGeneratorVersion = SvXMLImport::LO_7x;
213                     }
214                     else
215                     {
216                         SAL_INFO("xmloff.core", "unknown LO version: " << loVersion);
217                     }
218                     return; // ignore buildIds
219                 }
220             }
221         }
222         sal_Int32 nUPD, nBuild;
223         if ( !rImport.getBuildIds( nUPD, nBuild ) )
224             return;
225 
226         if ( nUPD >= 640 && nUPD <= 645 )
227         {
228             mnGeneratorVersion = SvXMLImport::OOo_1x;
229         }
230         else if ( nUPD == 680 )
231         {
232             mnGeneratorVersion = SvXMLImport::OOo_2x;
233         }
234         else if ( nUPD == 300 && nBuild <= 9379 )
235         {
236             mnGeneratorVersion = SvXMLImport::OOo_30x;
237         }
238         else if ( nUPD == 310 )
239         {
240             mnGeneratorVersion = SvXMLImport::OOo_31x;
241         }
242         else if ( nUPD == 320 )
243         {
244             mnGeneratorVersion = SvXMLImport::OOo_32x;
245         }
246         else if ( nUPD == 330 )
247         {
248             mnGeneratorVersion = SvXMLImport::OOo_33x;
249         }
250         else if ( nUPD == 340 )
251         {
252             mnGeneratorVersion = SvXMLImport::OOo_34x;
253         }
254         else if (nUPD == 400 || nUPD == 401)
255         {
256             mnGeneratorVersion = SvXMLImport::AOO_40x;
257         }
258         else if (nUPD >= 410)
259         {
260             // effectively this means "latest", see use
261             // in XMLGraphicsDefaultStyle::SetDefaults()!
262             mnGeneratorVersion = SvXMLImport::AOO_4x;
263         }
264     }
265 
getGeneratorVersion() const266     sal_uInt16 getGeneratorVersion() const
267     {
268         return mnGeneratorVersion;
269     }
270 };
271 
272 }
273 
274 class SvXMLImport_Impl
275 {
276 public:
277     FontToSubsFontConverter hBatsFontConv;
278     FontToSubsFontConverter hMathFontConv;
279 
280     bool mbOwnGraphicResolver;
281     bool mbOwnEmbeddedResolver;
282     INetURLObject aBaseURL;
283     INetURLObject aDocBase;
284 
285     /// name of stream in package, e.g., "content.xml"
286     OUString mStreamName;
287 
288     std::optional<OUString> mxODFVersion;
289 
290     bool mbIsOOoXML;
291 
292     // Boolean, indicating that position attributes
293     // of shapes are given in horizontal left-to-right layout. This is the case
294     // for the OpenOffice.org file format. (#i28749#)
295     bool mbShapePositionInHoriL2R;
296     bool mbTextDocInOOoFileFormat;
297 
298     const uno::Reference< uno::XComponentContext > mxComponentContext;
299     OUString implementationName;
300     css::uno::Sequence< OUString > maSupportedServiceNames;
301 
302     uno::Reference< embed::XStorage > mxSourceStorage;
303 
304     std::unique_ptr< xmloff::RDFaImportHelper > mpRDFaHelper;
305 
306     std::unique_ptr< DocumentInfo > mpDocumentInfo;
307 
SvXMLImport_Impl(const uno::Reference<uno::XComponentContext> & rxContext,OUString const & theImplementationName,const css::uno::Sequence<OUString> & sSupportedServiceNames={})308     SvXMLImport_Impl( const uno::Reference< uno::XComponentContext >& rxContext,
309                       OUString const & theImplementationName,
310                       const css::uno::Sequence< OUString > & sSupportedServiceNames = {})
311         : hBatsFontConv( nullptr )
312         , hMathFontConv( nullptr )
313         , mbOwnGraphicResolver( false )
314         , mbOwnEmbeddedResolver( false )
315         , mbIsOOoXML(false)
316         // Convert drawing object positions from OOo file format to OASIS (#i28749#)
317         , mbShapePositionInHoriL2R( false )
318         , mbTextDocInOOoFileFormat( false )
319         , mxComponentContext( rxContext )
320         , implementationName(theImplementationName)
321         , maSupportedServiceNames(sSupportedServiceNames)
322         , mpRDFaHelper() // lazy
323         , mpDocumentInfo() // lazy
324     {
325         SAL_WARN_IF(!mxComponentContext.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
326         if (!mxComponentContext.is()) throw uno::RuntimeException();
327         if (!maSupportedServiceNames.hasElements())
328             maSupportedServiceNames = { "com.sun.star.document.ImportFilter", "com.sun.star.xml.XMLImportFilter" };
329     }
330 
getGeneratorVersion(const SvXMLImport & rImport)331     sal_uInt16 getGeneratorVersion( const SvXMLImport& rImport )
332     {
333         if (!mpDocumentInfo)
334         {
335             mpDocumentInfo.reset( new DocumentInfo( rImport ) );
336         }
337 
338         return mpDocumentInfo->getGeneratorVersion();
339     }
340 
341     ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper;
342 };
343 
CreateFastContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> &)344 SvXMLImportContext *SvXMLImport::CreateFastContext( sal_Int32 nElement,
345         const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
346 {
347     assert(false);
348     SAL_WARN( "xmloff.core", "CreateFastContext should be overridden, for element " << nElement);
349     return new SvXMLImportContext( *this );
350 }
351 
InitCtor_()352 void SvXMLImport::InitCtor_()
353 {
354     if( mnImportFlags != SvXMLImportFlags::NONE )
355     {
356         // implicit "xml" namespace prefix
357         mpNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
358         mpNamespaceMap->Add( "_office", GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
359         mpNamespaceMap->Add( "_office_ooo", GetXMLToken(XML_N_OFFICE_EXT), XML_NAMESPACE_OFFICE_EXT );
360         mpNamespaceMap->Add( "_ooo", GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
361         mpNamespaceMap->Add( "_style", GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
362         mpNamespaceMap->Add( "_text", GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT );
363         mpNamespaceMap->Add( "_table", GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
364         mpNamespaceMap->Add( "_table_ooo", GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT );
365         mpNamespaceMap->Add( "_draw", GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
366         mpNamespaceMap->Add( "_draw_ooo", GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT );
367         mpNamespaceMap->Add( "_dr3d", GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D );
368         mpNamespaceMap->Add( "_fo", GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
369         mpNamespaceMap->Add( "_xlink", GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
370         mpNamespaceMap->Add( "_dc", GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
371         mpNamespaceMap->Add( "_dom", GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
372         mpNamespaceMap->Add( "_meta", GetXMLToken(XML_N_META), XML_NAMESPACE_META );
373         mpNamespaceMap->Add( "_number", GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
374         mpNamespaceMap->Add( "_svg", GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG );
375         mpNamespaceMap->Add( "_chart", GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART );
376         mpNamespaceMap->Add( "_math", GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
377         mpNamespaceMap->Add( "_form", GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM );
378         mpNamespaceMap->Add( "_script", GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT );
379         mpNamespaceMap->Add( "_config", GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
380         mpNamespaceMap->Add( "_xforms", GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS );
381         mpNamespaceMap->Add( "_formx", GetXMLToken( XML_N_FORMX ), XML_NAMESPACE_FORMX );
382         mpNamespaceMap->Add( "_xsd", GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD );
383         mpNamespaceMap->Add( "_xsi", GetXMLToken(XML_N_XSI), XML_NAMESPACE_XFORMS );
384         mpNamespaceMap->Add( "_ooow", GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
385         mpNamespaceMap->Add( "_oooc", GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
386         mpNamespaceMap->Add( "_field", GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
387         mpNamespaceMap->Add( "_of", GetXMLToken(XML_N_OF), XML_NAMESPACE_OF );
388         mpNamespaceMap->Add( "_xhtml", GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
389         mpNamespaceMap->Add( "_css3text", GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT );
390 
391         mpNamespaceMap->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
392         mpNamespaceMap->Add( "_office_libo",
393                              GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
394     }
395 
396     if (mxNumberFormatsSupplier.is())
397         mpNumImport = std::make_unique<SvXMLNumFmtHelper>(mxNumberFormatsSupplier, GetComponentContext());
398 
399     if (mxModel.is() && !mxEventListener.is())
400     {
401         mxEventListener.set(new SvXMLImportEventListener(this));
402         mxModel->addEventListener(mxEventListener);
403     }
404 }
405 
SvXMLImport(const css::uno::Reference<css::uno::XComponentContext> & xContext,OUString const & implementationName,SvXMLImportFlags nImportFlags,const css::uno::Sequence<OUString> & sSupportedServiceNames)406 SvXMLImport::SvXMLImport(
407     const css::uno::Reference< css::uno::XComponentContext >& xContext,
408     OUString const & implementationName,
409     SvXMLImportFlags nImportFlags,
410     const css::uno::Sequence< OUString > & sSupportedServiceNames )
411 :   mpImpl( new SvXMLImport_Impl(xContext, implementationName, sSupportedServiceNames) ),
412     mpNamespaceMap( new SvXMLNamespaceMap ),
413 
414     mpUnitConv( new SvXMLUnitConverter( xContext,
415                 util::MeasureUnit::MM_100TH, util::MeasureUnit::MM_100TH,
416                 SvtSaveOptions::ODFSVER_LATEST_EXTENDED) ),
417 
418     mnImportFlags( nImportFlags ),
419     maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
420     mbIsFormsSupported( true ),
421     mbIsTableShapeSupported( false ),
422     mbNotifyMacroEventRead( false )
423 {
424     SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
425     InitCtor_();
426     mxParser = xml::sax::FastParser::create( xContext );
427     setNamespaceHandler( maNamespaceHandler );
428     setTokenHandler( xTokenHandler  );
429     if ( !bIsNSMapsInitialized )
430     {
431         initializeNamespaceMaps();
432         bIsNSMapsInitialized = true;
433     }
434     registerNamespaces();
435     maNamespaceAttrList = new comphelper::AttributeList;
436 }
437 
cleanup()438 void SvXMLImport::cleanup() noexcept
439 {
440     if (mxEventListener.is() && mxModel.is())
441         mxModel->removeEventListener(mxEventListener);
442     // clear context stacks first in case of parse error because the context
443     // class dtors are full of application logic
444     while (!maContexts.empty())
445     {
446         if (SvXMLStylesContext* pStylesContext = dynamic_cast<SvXMLStylesContext*>(maContexts.top().get()))
447             pStylesContext->dispose();
448         maContexts.pop();
449     }
450     if( mxTextImport )
451         mxTextImport->dispose();
452     mxTextImport.clear(); // XMLRedlineImportHelper needs model
453     DisposingModel();
454 }
455 
~SvXMLImport()456 SvXMLImport::~SvXMLImport() noexcept
457 {
458     cleanup();
459 }
460 
addEmbeddedFont(const css::uno::Reference<css::io::XInputStream> & stream,const OUString & fontName,const char * extra,std::vector<unsigned char> const & key,bool eot)461 bool SvXMLImport::addEmbeddedFont(const css::uno::Reference< css::io::XInputStream >& stream,
462                                   const OUString& fontName, const char* extra,
463                                   std::vector<unsigned char> const & key, bool eot)
464 {
465     if (!mxEmbeddedFontHelper)
466         mxEmbeddedFontHelper.reset(new EmbeddedFontsHelper);
467     return mxEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key, eot);
468 }
469 
getUnoTunnelId()470 const css::uno::Sequence<sal_Int8>& SvXMLImport::getUnoTunnelId() noexcept
471 {
472     static const UnoTunnelIdInit theSvXMLImportUnoTunnelId;
473     return theSvXMLImportUnoTunnelId.getSeq();
474 }
475 
476 // XUnoTunnel
getSomething(const uno::Sequence<sal_Int8> & rId)477 sal_Int64 SAL_CALL SvXMLImport::getSomething( const uno::Sequence< sal_Int8 >& rId )
478 {
479     if( isUnoTunnelId<SvXMLImport>(rId) )
480     {
481         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
482     }
483     return 0;
484 }
485 
486 namespace
487 {
488     class setFastDocumentHandlerGuard
489     {
490     private:
491         css::uno::Reference<css::xml::sax::XFastParser> mxParser;
492     public:
setFastDocumentHandlerGuard(const css::uno::Reference<css::xml::sax::XFastParser> & Parser,const css::uno::Reference<css::xml::sax::XFastDocumentHandler> & Handler)493         setFastDocumentHandlerGuard(const css::uno::Reference<css::xml::sax::XFastParser>& Parser,
494                                     const css::uno::Reference<css::xml::sax::XFastDocumentHandler>& Handler)
495             : mxParser(Parser)
496         {
497             mxParser->setFastDocumentHandler(Handler);
498         }
499         //guarantee restoration of null document handler
~setFastDocumentHandlerGuard()500         ~setFastDocumentHandlerGuard()
501         {
502             mxParser->setFastDocumentHandler(nullptr);
503         }
504     };
505 }
506 
507 // XFastParser
parseStream(const xml::sax::InputSource & aInputSource)508 void SAL_CALL SvXMLImport::parseStream( const xml::sax::InputSource& aInputSource )
509 {
510     setFastDocumentHandlerGuard aDocumentHandlerGuard(mxParser, mxFastDocumentHandler.is() ? mxFastDocumentHandler : this);
511     mxParser->parseStream(aInputSource);
512 }
513 
setFastDocumentHandler(const uno::Reference<xml::sax::XFastDocumentHandler> & Handler)514 void SAL_CALL SvXMLImport::setFastDocumentHandler( const uno::Reference< xml::sax::XFastDocumentHandler >& Handler )
515 {
516     mxFastDocumentHandler = Handler;
517 }
518 
setTokenHandler(const uno::Reference<xml::sax::XFastTokenHandler> & Handler)519 void SAL_CALL SvXMLImport::setTokenHandler( const uno::Reference< xml::sax::XFastTokenHandler >& Handler )
520 {
521     mxParser->setTokenHandler( Handler );
522 }
523 
registerNamespace(const OUString & NamespaceURL,sal_Int32 NamespaceToken)524 void SAL_CALL SvXMLImport::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken )
525 {
526     mxParser->registerNamespace( NamespaceURL, NamespaceToken );
527 }
528 
getNamespaceURL(const OUString & rPrefix)529 OUString SAL_CALL SvXMLImport::getNamespaceURL( const OUString& rPrefix )
530 {
531     return mxParser->getNamespaceURL( rPrefix );
532 }
533 
setErrorHandler(const uno::Reference<xml::sax::XErrorHandler> & Handler)534 void SAL_CALL SvXMLImport::setErrorHandler( const uno::Reference< xml::sax::XErrorHandler >& Handler )
535 {
536     mxParser->setErrorHandler( Handler );
537 }
538 
setEntityResolver(const uno::Reference<xml::sax::XEntityResolver> & Resolver)539 void SAL_CALL SvXMLImport::setEntityResolver( const uno::Reference< xml::sax::XEntityResolver >& Resolver )
540 {
541     mxParser->setEntityResolver( Resolver );
542 }
543 
setLocale(const lang::Locale & rLocale)544 void SAL_CALL SvXMLImport::setLocale( const lang::Locale& rLocale )
545 {
546     mxParser->setLocale( rLocale );
547 }
548 
setNamespaceHandler(const uno::Reference<xml::sax::XFastNamespaceHandler> & Handler)549 void SAL_CALL SvXMLImport::setNamespaceHandler( const uno::Reference< xml::sax::XFastNamespaceHandler >& Handler)
550 {
551     mxParser->setNamespaceHandler( Handler );
552 }
553 
setCustomEntityNames(const::css::uno::Sequence<::css::beans::Pair<::rtl::OUString,::rtl::OUString>> & replacements)554 void SAL_CALL SvXMLImport::setCustomEntityNames( const ::css::uno::Sequence< ::css::beans::Pair<::rtl::OUString, ::rtl::OUString> >& replacements )
555 {
556     mxParser->setCustomEntityNames( replacements );
557 }
558 
startDocument()559 void SAL_CALL SvXMLImport::startDocument()
560 {
561     SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
562     if (mxGraphicStorageHandler.is() && mxEmbeddedResolver.is())
563         return;
564 
565     Reference< lang::XMultiServiceFactory > xFactory( mxModel,  UNO_QUERY );
566     if( !xFactory.is() )
567         return;
568 
569     try
570     {
571         if (!mxGraphicStorageHandler.is())
572         {
573             // #99870# Import... instead of Export...
574             mxGraphicStorageHandler.set(
575                 xFactory->createInstance("com.sun.star.document.ImportGraphicStorageHandler"),
576                 UNO_QUERY);
577             mpImpl->mbOwnGraphicResolver = mxGraphicStorageHandler.is();
578         }
579 
580         if( !mxEmbeddedResolver.is() )
581         {
582             // #99870# Import... instead of Export...
583             mxEmbeddedResolver.set(
584                 xFactory->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"),
585                 UNO_QUERY);
586             mpImpl->mbOwnEmbeddedResolver = mxEmbeddedResolver.is();
587         }
588     }
589     catch( css::uno::Exception& )
590     {
591     }
592 }
593 
endDocument()594 void SAL_CALL SvXMLImport::endDocument()
595 {
596     SAL_INFO( "xmloff.core", "} SvXMLImport::endDocument" );
597     //  #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
598     //  because the SvXMLImport dtor might not be called until after the document has been closed.
599 
600     GetTextImport()->MapCrossRefHeadingFieldsHorribly();
601 
602     if (mpImpl->mpRDFaHelper)
603     {
604         const uno::Reference<rdf::XRepositorySupplier> xRS(mxModel,
605             uno::UNO_QUERY);
606         if (xRS.is())
607         {
608             mpImpl->mpRDFaHelper->InsertRDFa( xRS );
609         }
610     }
611 
612     mpNumImport.reset();
613     if (mxImportInfo.is())
614     {
615         uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
616         if (xPropertySetInfo.is())
617         {
618             if (bool(mpProgressBarHelper))
619             {
620                 OUString sProgressMax(XML_PROGRESSMAX);
621                 OUString sProgressCurrent(XML_PROGRESSCURRENT);
622                 OUString sRepeat(XML_PROGRESSREPEAT);
623                 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
624                     xPropertySetInfo->hasPropertyByName(sProgressCurrent))
625                 {
626                     sal_Int32 nProgressMax(mpProgressBarHelper->GetReference());
627                     sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue());
628                     mxImportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax));
629                     mxImportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent));
630                 }
631                 if (xPropertySetInfo->hasPropertyByName(sRepeat))
632                     mxImportInfo->setPropertyValue(sRepeat, css::uno::makeAny(mpProgressBarHelper->GetRepeat()));
633                 // pProgressBarHelper is deleted in dtor
634             }
635             OUString sNumberStyles(XML_NUMBERSTYLES);
636             if (mxNumberStyles.is() && xPropertySetInfo->hasPropertyByName(sNumberStyles))
637             {
638                 mxImportInfo->setPropertyValue(sNumberStyles, Any(mxNumberStyles));
639             }
640         }
641     }
642 
643     if( mxFontDecls.is() )
644         mxFontDecls->dispose();
645     if( mxStyles.is() )
646         mxStyles->dispose();
647     if( mxAutoStyles.is() )
648         mxAutoStyles->dispose();
649     if( mxMasterStyles.is() )
650         mxMasterStyles->dispose();
651 
652     // possible form-layer related knittings which can only be done when
653     // the whole document exists
654     if ( mxFormImport.is() )
655         mxFormImport->documentDone();
656 
657     //  The shape import helper does the z-order sorting in the dtor,
658     //  so it must be deleted here, too.
659     mxShapeImport = nullptr;
660 
661     if( mpImpl->mbOwnGraphicResolver )
662     {
663         Reference<lang::XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
664         xComp->dispose();
665     }
666 
667     if( mpImpl->mbOwnEmbeddedResolver )
668     {
669         Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
670         xComp->dispose();
671     }
672     mpStyleMap.clear();
673 
674     if ( bool( mpXMLErrors ) )
675     {
676         mpXMLErrors->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE );
677     }
678 }
679 
processNSAttributes(std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,SvXMLImport * const pImport,const uno::Reference<xml::sax::XAttributeList> & xAttrList)680 std::unique_ptr<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
681         std::unique_ptr<SvXMLNamespaceMap> & rpNamespaceMap,
682         SvXMLImport *const pImport, // TODO???
683         const uno::Reference< xml::sax::XAttributeList >& xAttrList)
684 {
685     std::unique_ptr<SvXMLNamespaceMap> pRewindMap;
686     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
687     for( sal_Int16 i=0; i < nAttrCount; i++ )
688     {
689         const OUString& rAttrName = xAttrList->getNameByIndex( i );
690         if (pImport && rAttrName == "office:version" && !pImport->mpImpl->mxODFVersion)
691         {
692             pImport->mpImpl->mxODFVersion = xAttrList->getValueByIndex( i );
693 
694             // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
695             if (pImport->mpImpl->mStreamName == "content.xml"
696                 && !pImport->IsODFVersionConsistent(*pImport->mpImpl->mxODFVersion))
697             {
698                 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
699                         uno::Reference< uno::XInterface >(),
700                         uno::makeAny(
701                             packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
702             }
703         }
704         else if( ( rAttrName.getLength() >= 5 ) &&
705             ( rAttrName.startsWith( GetXMLToken(XML_XMLNS) ) ) &&
706             ( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
707         {
708             if( !pRewindMap )
709             {
710                 pRewindMap = std::move(rpNamespaceMap);
711                 rpNamespaceMap.reset(new SvXMLNamespaceMap(*pRewindMap));
712             }
713             const OUString& rAttrValue = xAttrList->getValueByIndex( i );
714 
715             OUString aPrefix( ( rAttrName.getLength() == 5 )
716                                  ? OUString()
717                                  : rAttrName.copy( 6 ) );
718             // Add namespace, but only if it is known.
719             sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
720             // If namespace is unknown, try to match a name with similar
721             // TC Id and version
722             if( XML_NAMESPACE_UNKNOWN == nKey  )
723             {
724                 OUString aTestName( rAttrValue );
725                 if( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
726                     nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName );
727             }
728             // If that namespace is not known, too, add it as unknown
729             if( XML_NAMESPACE_UNKNOWN == nKey  )
730                 rpNamespaceMap->Add( aPrefix, rAttrValue );
731 
732         }
733     }
734     return pRewindMap;
735 }
736 
737 
characters(const OUString & rChars)738 void SAL_CALL SvXMLImport::characters( const OUString& rChars )
739 {
740     maContexts.top()->characters( rChars );
741 }
742 
processingInstruction(const OUString &,const OUString &)743 void SAL_CALL SvXMLImport::processingInstruction( const OUString&,
744                                        const OUString& )
745 {
746 }
747 
setDocumentLocator(const uno::Reference<xml::sax::XLocator> & rLocator)748 void SAL_CALL SvXMLImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
749 {
750     mxLocator = rLocator;
751 }
752 
753 // XFastContextHandler
startFastElement(sal_Int32 Element,const uno::Reference<xml::sax::XFastAttributeList> & Attribs)754 void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element,
755     const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
756 {
757     SAL_INFO("xmloff.core", "startFastElement " << SvXMLImport::getNameFromToken( Element ));
758     if ( Attribs.is() && !mpImpl->mxODFVersion)
759     {
760         sax_fastparser::FastAttributeList& rAttribList =
761             sax_fastparser::castToFastAttributeList( Attribs );
762         auto aIter( rAttribList.find( XML_ELEMENT( OFFICE, XML_VERSION ) ) );
763         if( aIter != rAttribList.end() )
764         {
765             mpImpl->mxODFVersion = aIter.toString();
766 
767             // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
768             if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( *mpImpl->mxODFVersion ) )
769             {
770                 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
771                         uno::Reference< uno::XInterface >(),
772                         uno::makeAny(
773                             packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
774             }
775         }
776     }
777 
778     maNamespaceAttrList->Clear();
779 
780     maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList );
781     std::unique_ptr<SvXMLNamespaceMap> pRewindMap = processNSAttributes(mpNamespaceMap, this, maNamespaceAttrList);
782 
783     SvXMLImportContextRef xContext;
784     const bool bRootContext = maContexts.empty();
785     if (!maContexts.empty())
786     {
787         const SvXMLImportContextRef & pHandler = maContexts.top();
788         SAL_INFO("xmloff.core", "calling createFastChildContext on " << typeid(*pHandler.get()).name());
789         auto tmp = pHandler->createFastChildContext( Element, Attribs );
790         xContext = dynamic_cast<SvXMLImportContext*>(tmp.get());
791         assert((tmp && xContext) || (!tmp && !xContext));
792     }
793     else
794         xContext.set( CreateFastContext( Element, Attribs ) );
795 
796     SAL_INFO_IF(!xContext.is(), "xmloff.core", "No fast context for element " << getNameFromToken(Element));
797     if (bRootContext && !xContext)
798     {
799         OUString aName = getNameFromToken(Element);
800         SetError( XMLERROR_FLAG_SEVERE | XMLERROR_UNKNOWN_ROOT,
801                   { aName }, "Root element " + aName + " unknown", Reference<xml::sax::XLocator>() );
802     }
803     if ( !xContext )
804         xContext.set( new SvXMLImportContext( *this ) );
805 
806     // Remember old namespace map.
807     if( pRewindMap )
808         xContext->PutRewindMap(std::move(pRewindMap));
809 
810     // Call a startElement at the new context.
811     xContext->startFastElement( Element, Attribs );
812 
813     // Push context on stack.
814     maContexts.push(xContext);
815 }
816 
startUnknownElement(const OUString & rNamespace,const OUString & rName,const uno::Reference<xml::sax::XFastAttributeList> & Attribs)817 void SAL_CALL SvXMLImport::startUnknownElement (const OUString & rNamespace, const OUString & rName,
818     const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
819 {
820     SAL_INFO("xmloff.core", "startUnknownElement " << rNamespace << " " << rName);
821     SvXMLImportContextRef xContext;
822     const bool bRootContext = maContexts.empty();
823     if (!maContexts.empty())
824     {
825         const SvXMLImportContextRef & pHandler = maContexts.top();
826         SAL_INFO("xmloff.core", "calling createUnknownChildContext on " << typeid(*pHandler.get()).name());
827         auto tmp = pHandler->createUnknownChildContext( rNamespace, rName, Attribs );
828         xContext = dynamic_cast<SvXMLImportContext*>(tmp.get());
829         assert((tmp && xContext) || (!tmp && !xContext));
830     }
831     else
832         xContext.set( CreateFastContext( -1, Attribs ) );
833 
834     SAL_WARN_IF(!xContext.is(), "xmloff.core", "No context for unknown-element " << rNamespace << " " << rName);
835     if (bRootContext && !xContext)
836     {
837         SetError( XMLERROR_FLAG_SEVERE | XMLERROR_UNKNOWN_ROOT,
838                   { rName }, "Root element " + rName + " unknown", Reference<xml::sax::XLocator>() );
839     }
840     if (!xContext)
841     {
842         if (!maContexts.empty())
843             // This is pretty weird, but it's what the code did before I simplified it, and some parts of the
844             // code rely on this behaviour e.g. DocumentBuilderContext
845             xContext = maContexts.top();
846         else
847             xContext = new SvXMLImportContext( *this );
848     }
849 
850     xContext->startUnknownElement( rNamespace, rName, Attribs );
851     maContexts.push(xContext);
852 }
853 
endFastElement(sal_Int32 Element)854 void SAL_CALL SvXMLImport::endFastElement (sal_Int32 Element)
855 {
856     SAL_INFO("xmloff.core", "endFastElement " << SvXMLImport::getNameFromToken( Element ));
857     if (maContexts.empty())
858     {
859         SAL_WARN("xmloff.core", "SvXMLImport::endFastElement: no context left");
860         assert(false);
861         return;
862     }
863     SvXMLImportContextRef xContext = std::move(maContexts.top());
864     // Get a namespace map to rewind.
865     std::unique_ptr<SvXMLNamespaceMap> pRewindMap = xContext->TakeRewindMap();
866     maContexts.pop();
867     xContext->endFastElement( Element );
868     // Rewind a namespace map.
869     if (pRewindMap)
870         mpNamespaceMap = std::move(pRewindMap);
871 }
872 
endUnknownElement(const OUString & rPrefix,const OUString & rLocalName)873 void SAL_CALL SvXMLImport::endUnknownElement (const OUString & rPrefix, const OUString & rLocalName)
874 {
875     SAL_INFO("xmloff.core", "endUnknownElement " << rPrefix << " " << rLocalName);
876     if (maContexts.empty())
877     {
878         SAL_WARN("xmloff.core", "SvXMLImport::endUnknownElement: no context left");
879         assert(false);
880         return;
881     }
882     SvXMLImportContextRef xContext = std::move(maContexts.top());
883     maContexts.pop();
884     xContext->endUnknownElement( rPrefix, rLocalName );
885 }
886 
887 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
createFastChildContext(sal_Int32,const uno::Reference<xml::sax::XFastAttributeList> &)888     SvXMLImport::createFastChildContext (sal_Int32,
889     const uno::Reference< xml::sax::XFastAttributeList > &)
890 {
891     return this;
892 }
893 
894 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
createUnknownChildContext(const OUString &,const OUString &,const uno::Reference<xml::sax::XFastAttributeList> &)895     SvXMLImport::createUnknownChildContext (const OUString &, const OUString &,
896     const uno::Reference< xml::sax::XFastAttributeList > &)
897 {
898     return this;
899 }
900 
SetStatistics(const uno::Sequence<beans::NamedValue> &)901 void SvXMLImport::SetStatistics(const uno::Sequence< beans::NamedValue> &)
902 {
903     GetProgressBarHelper()->SetRepeat(false);
904     GetProgressBarHelper()->SetReference(0);
905 }
906 
907 // XImporter
setTargetDocument(const uno::Reference<lang::XComponent> & xDoc)908 void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
909 {
910     mxModel.set( xDoc, UNO_QUERY );
911     if( !mxModel.is() )
912         throw lang::IllegalArgumentException();
913 
914     try
915     {
916         uno::Reference<document::XStorageBasedDocument> const xSBDoc(mxModel, uno::UNO_QUERY);
917         uno::Reference<embed::XStorage> const xStor(xSBDoc.is() ? xSBDoc->getDocumentStorage()
918                                                                 : nullptr);
919         if (xStor.is())
920         {
921             mpImpl->mbIsOOoXML =
922                 ::comphelper::OStorageHelper::GetXStorageFormat(xStor)
923                    < SOFFICE_FILEFORMAT_8;
924         }
925     }
926     catch (uno::Exception const&)
927     {
928         DBG_UNHANDLED_EXCEPTION("xmloff.core");
929     }
930     if (!mxEventListener.is())
931     {
932         mxEventListener.set(new SvXMLImportEventListener(this));
933         mxModel->addEventListener(mxEventListener);
934     }
935 
936     SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "number format import already exists." );
937     mpNumImport.reset();
938 }
939 
940 // XFilter
filter(const uno::Sequence<beans::PropertyValue> &)941 sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& )
942 {
943     return false;
944 }
945 
cancel()946 void SAL_CALL SvXMLImport::cancel(  )
947 {
948 }
949 
950 // XInitialize
initialize(const uno::Sequence<uno::Any> & aArguments)951 void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
952 {
953     for( const auto& rAny : aArguments )
954     {
955         Reference<XInterface> xValue;
956         rAny >>= xValue;
957 
958         uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
959             xValue, UNO_QUERY );
960         if( xTmpStatusIndicator.is() )
961             mxStatusIndicator = xTmpStatusIndicator;
962 
963         uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
964         if (xGraphicStorageHandler.is())
965             mxGraphicStorageHandler = xGraphicStorageHandler;
966 
967         uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
968             xValue, UNO_QUERY );
969         if( xTmpObjectResolver.is() )
970             mxEmbeddedResolver = xTmpObjectResolver;
971 
972         uno::Reference<beans::XPropertySet> xTmpPropSet( xValue, UNO_QUERY );
973         if( xTmpPropSet.is() )
974         {
975             mxImportInfo = xTmpPropSet;
976             uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
977             if (xPropertySetInfo.is())
978             {
979                 OUString sPropName(XML_NUMBERSTYLES);
980                 if (xPropertySetInfo->hasPropertyByName(sPropName))
981                 {
982                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
983                     aAny >>= mxNumberStyles;
984                 }
985 
986                 sPropName = "PrivateData";
987                 if (xPropertySetInfo->hasPropertyByName(sPropName))
988                 {
989                     Reference < XInterface > xIfc;
990                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
991                     aAny >>= xIfc;
992 
993                     StyleMap *pSMap = comphelper::getUnoTunnelImplementation<StyleMap>( xIfc );
994                     if( pSMap )
995                     {
996                         mpStyleMap = pSMap;
997                     }
998                 }
999                 OUString sBaseURI;
1000                 sPropName = "BaseURI";
1001                 if (xPropertySetInfo->hasPropertyByName(sPropName))
1002                 {
1003                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1004                     aAny >>= sBaseURI;
1005                     mpImpl->aBaseURL.SetURL( sBaseURI );
1006                     mpImpl->aDocBase.SetURL( sBaseURI );
1007                 }
1008                 OUString sRelPath;
1009                 sPropName = "StreamRelPath";
1010                 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1011                 {
1012                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1013                     aAny >>= sRelPath;
1014                 }
1015                 OUString sName;
1016                 sPropName = "StreamName";
1017                 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1018                 {
1019                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1020                     aAny >>= sName;
1021                 }
1022                 if( !sBaseURI.isEmpty() && !sName.isEmpty() )
1023                 {
1024                     if( !sRelPath.isEmpty() )
1025                         mpImpl->aBaseURL.insertName( sRelPath );
1026                     mpImpl->aBaseURL.insertName( sName );
1027                 }
1028                 mpImpl->mStreamName = sName; // Note: may be empty (XSLT)
1029                 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1030                 sPropName = "ShapePositionInHoriL2R";
1031                 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1032                 {
1033                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1034                     aAny >>= mpImpl->mbShapePositionInHoriL2R;
1035                 }
1036                 sPropName = "TextDocInOOoFileFormat";
1037                 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1038                 {
1039                     uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1040                     aAny >>= mpImpl->mbTextDocInOOoFileFormat;
1041                 }
1042 
1043                 sPropName = "SourceStorage";
1044                 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1045                     mxImportInfo->getPropertyValue(sPropName) >>= mpImpl->mxSourceStorage;
1046             }
1047         }
1048     }
1049 
1050     uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW);
1051     uno::Sequence<uno::Any> args(1);
1052     args[0] <<= OUString("IgnoreMissingNSDecl");
1053     xInit->initialize( args );
1054 }
1055 
1056 // XServiceInfo
getImplementationName()1057 OUString SAL_CALL SvXMLImport::getImplementationName()
1058 {
1059     return mpImpl->implementationName;
1060 }
1061 
supportsService(const OUString & rServiceName)1062 sal_Bool SAL_CALL SvXMLImport::supportsService( const OUString& rServiceName )
1063 {
1064     return cppu::supportsService(this, rServiceName);
1065 }
1066 
getSupportedServiceNames()1067 uno::Sequence< OUString > SAL_CALL SvXMLImport::getSupportedServiceNames(  )
1068 {
1069     return mpImpl->maSupportedServiceNames;
1070 }
1071 
CreateTextImport()1072 XMLTextImportHelper* SvXMLImport::CreateTextImport()
1073 {
1074     return new XMLTextImportHelper( mxModel, *this );
1075 }
1076 
CreateShapeImport()1077 XMLShapeImportHelper* SvXMLImport::CreateShapeImport()
1078 {
1079     return new XMLShapeImportHelper( *this, mxModel );
1080 }
1081 
CreateChartImport()1082 SchXMLImportHelper* SvXMLImport::CreateChartImport()
1083 {
1084     return new SchXMLImportHelper();
1085 }
1086 
CreateFormImport()1087 ::xmloff::OFormLayerXMLImport* SvXMLImport::CreateFormImport()
1088 {
1089     return new ::xmloff::OFormLayerXMLImport(*this);
1090 }
1091 
1092 
1093 // Get or create fill/line/lineend-style-helper
1094 
1095 
GetGradientHelper()1096 const Reference< container::XNameContainer > & SvXMLImport::GetGradientHelper()
1097 {
1098     if( !mxGradientHelper.is() )
1099     {
1100         if( mxModel.is() )
1101         {
1102             Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1103             if( xServiceFact.is() )
1104             {
1105                 try
1106                 {
1107                     mxGradientHelper.set( xServiceFact->createInstance(
1108                         "com.sun.star.drawing.GradientTable" ), UNO_QUERY);
1109                 }
1110                 catch( lang::ServiceNotRegisteredException& )
1111                 {}
1112             }
1113         }
1114     }
1115 
1116     return mxGradientHelper;
1117 }
1118 
GetHatchHelper()1119 const Reference< container::XNameContainer > & SvXMLImport::GetHatchHelper()
1120 {
1121     if( !mxHatchHelper.is() )
1122     {
1123         if( mxModel.is() )
1124         {
1125             Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1126             if( xServiceFact.is() )
1127             {
1128                 try
1129                 {
1130                     mxHatchHelper.set( xServiceFact->createInstance(
1131                         "com.sun.star.drawing.HatchTable" ), UNO_QUERY);
1132                 }
1133                 catch( lang::ServiceNotRegisteredException& )
1134                 {}
1135             }
1136         }
1137     }
1138 
1139     return mxHatchHelper;
1140 }
1141 
GetBitmapHelper()1142 const Reference< container::XNameContainer > & SvXMLImport::GetBitmapHelper()
1143 {
1144     if( !mxBitmapHelper.is() )
1145     {
1146         if( mxModel.is() )
1147         {
1148             Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1149             if( xServiceFact.is() )
1150             {
1151                 try
1152                 {
1153                     mxBitmapHelper.set( xServiceFact->createInstance(
1154                         "com.sun.star.drawing.BitmapTable" ), UNO_QUERY);
1155                 }
1156                 catch( lang::ServiceNotRegisteredException& )
1157                 {}
1158             }
1159         }
1160     }
1161 
1162     return mxBitmapHelper;
1163 }
1164 
GetTransGradientHelper()1165 const Reference< container::XNameContainer > & SvXMLImport::GetTransGradientHelper()
1166 {
1167     if( !mxTransGradientHelper.is() )
1168     {
1169         if( mxModel.is() )
1170         {
1171             Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1172             if( xServiceFact.is() )
1173             {
1174                 try
1175                 {
1176                     mxTransGradientHelper.set( xServiceFact->createInstance(
1177                         "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY);
1178                 }
1179                 catch( lang::ServiceNotRegisteredException& )
1180                 {}
1181             }
1182         }
1183     }
1184 
1185     return mxTransGradientHelper;
1186 }
1187 
GetMarkerHelper()1188 const Reference< container::XNameContainer > & SvXMLImport::GetMarkerHelper()
1189 {
1190     if( !mxMarkerHelper.is() )
1191     {
1192         if( mxModel.is() )
1193         {
1194             Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1195             if( xServiceFact.is() )
1196             {
1197                 try
1198                 {
1199                     mxMarkerHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY);
1200                 }
1201                 catch( lang::ServiceNotRegisteredException& )
1202                 {}
1203             }
1204         }
1205     }
1206 
1207     return mxMarkerHelper;
1208 }
1209 
GetDashHelper()1210 const Reference< container::XNameContainer > & SvXMLImport::GetDashHelper()
1211 {
1212     if( !mxDashHelper.is() && mxModel.is() )
1213     {
1214         Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
1215         if( xServiceFact.is() )
1216         {
1217             try
1218             {
1219                 mxDashHelper.set( xServiceFact->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY);
1220             }
1221             catch( lang::ServiceNotRegisteredException& )
1222             {}
1223         }
1224     }
1225 
1226     return mxDashHelper;
1227 }
1228 
IsPackageURL(const OUString & rURL) const1229 bool SvXMLImport::IsPackageURL( const OUString& rURL ) const
1230 {
1231 
1232     // if, and only if, only parts are imported, then we're in a package
1233     const SvXMLImportFlags nTest = SvXMLImportFlags::META|SvXMLImportFlags::STYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SETTINGS;
1234     if( (mnImportFlags & nTest) == nTest )
1235         return false;
1236 
1237     // TODO: from this point extract to own static function
1238 
1239     // Some quick tests: Some may rely on the package structure!
1240     sal_Int32 nLen = rURL.getLength();
1241     if( nLen > 0 && '/' == rURL[0] )
1242         // RFC2396 net_path or abs_path
1243         return false;
1244     else if( nLen > 1 && '.' == rURL[0] )
1245     {
1246         if( '.' == rURL[1] )
1247             // ../: We are never going up one level, so we know
1248             // it's not an external URI
1249             return false;
1250         else if( '/' == rURL[1] )
1251             // we are remaining on a level, so it's a package URI
1252             return true;
1253     }
1254 
1255     // Now check for a RFC2396 schema
1256     sal_Int32 nPos = 1;
1257     while( nPos < nLen )
1258     {
1259         switch( rURL[nPos] )
1260         {
1261         case '/':
1262             // a relative path segment
1263             return true;
1264         case ':':
1265             // a schema
1266             return false;
1267         default:
1268             break;
1269             // we don't care about any other characters
1270         }
1271         ++nPos;
1272     }
1273 
1274     return true;
1275 }
1276 
loadGraphicByURL(OUString const & rURL)1277 uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const & rURL)
1278 {
1279     uno::Reference<graphic::XGraphic> xGraphic;
1280 
1281     if (mxGraphicStorageHandler.is())
1282     {
1283         if (IsPackageURL(rURL))
1284         {
1285             xGraphic = mxGraphicStorageHandler->loadGraphic(rURL);
1286         }
1287         else
1288         {
1289             OUString const & rAbsoluteURL = GetAbsoluteReference(rURL);
1290             GraphicExternalLink aExternalLink(rAbsoluteURL);
1291             Graphic aGraphic(aExternalLink);
1292             xGraphic = aGraphic.GetXGraphic();
1293         }
1294     }
1295 
1296     return xGraphic;
1297 }
1298 
loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream)1299 uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream)
1300 {
1301     uno::Reference<graphic::XGraphic> xGraphic;
1302 
1303     if (mxGraphicStorageHandler.is())
1304     {
1305         xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream);
1306     }
1307 
1308     return xGraphic;
1309 }
1310 
GetStreamForGraphicObjectURLFromBase64() const1311 Reference< XOutputStream > SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const
1312 {
1313     Reference< XOutputStream > xOStm;
1314     Reference< document::XBinaryStreamResolver > xStmResolver(mxGraphicStorageHandler, UNO_QUERY);
1315 
1316     if( xStmResolver.is() )
1317         xOStm = xStmResolver->createOutputStream();
1318 
1319     return xOStm;
1320 }
1321 
ResolveEmbeddedObjectURL(const OUString & rURL,std::u16string_view rClassId)1322 OUString SvXMLImport::ResolveEmbeddedObjectURL(
1323                                     const OUString& rURL,
1324                                     std::u16string_view rClassId )
1325 {
1326     OUString sRet;
1327 
1328     if( IsPackageURL( rURL ) )
1329     {
1330         if ( mxEmbeddedResolver.is() )
1331         {
1332             OUString sURL( rURL );
1333             if( !rClassId.empty() )
1334             {
1335                 sURL += OUString::Concat("!") + rClassId;
1336             }
1337             sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( sURL );
1338         }
1339     }
1340     else
1341         sRet = GetAbsoluteReference( rURL );
1342 
1343     return sRet;
1344 }
1345 
GetSourceStorage() const1346 Reference< embed::XStorage > const & SvXMLImport::GetSourceStorage() const
1347 {
1348     return mpImpl->mxSourceStorage;
1349 }
1350 
1351 Reference < XOutputStream >
GetStreamForEmbeddedObjectURLFromBase64() const1352         SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const
1353 {
1354     Reference < XOutputStream > xOLEStream;
1355 
1356     if( mxEmbeddedResolver.is() )
1357     {
1358         Reference< XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY );
1359         if( xNA.is() )
1360         {
1361             Any aAny = xNA->getByName( "Obj12345678" );
1362             aAny >>= xOLEStream;
1363         }
1364     }
1365 
1366     return xOLEStream;
1367 }
1368 
ResolveEmbeddedObjectURLFromBase64()1369 OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1370 {
1371     OUString sRet;
1372 
1373     if( mxEmbeddedResolver.is() )
1374     {
1375         sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( "Obj12345678" );
1376     }
1377 
1378     return sRet;
1379 }
1380 
AddStyleDisplayName(XmlStyleFamily nFamily,const OUString & rName,const OUString & rDisplayName)1381 void SvXMLImport::AddStyleDisplayName( XmlStyleFamily nFamily,
1382                                        const OUString& rName,
1383                                        const OUString& rDisplayName )
1384 {
1385     if( !mpStyleMap.is() )
1386     {
1387         mpStyleMap = new StyleMap;
1388         if( mxImportInfo.is() )
1389         {
1390             OUString sPrivateData( "PrivateData" );
1391             Reference< beans::XPropertySetInfo > xPropertySetInfo =
1392                 mxImportInfo->getPropertySetInfo();
1393             if( xPropertySetInfo.is() &&
1394                 xPropertySetInfo->hasPropertyByName(sPrivateData) )
1395             {
1396                 Reference < XInterface > xIfc(
1397                         static_cast< XUnoTunnel *>( mpStyleMap.get() ) );
1398                 mxImportInfo->setPropertyValue( sPrivateData, Any(xIfc) );
1399             }
1400         }
1401     }
1402 
1403     StyleMap::key_type aKey( nFamily, rName );
1404     StyleMap::value_type aValue( aKey, rDisplayName );
1405     ::std::pair<StyleMap::iterator,bool> aRes( mpStyleMap->insert( aValue ) );
1406     SAL_WARN_IF( !aRes.second,
1407                  "xmloff.core",
1408        "duplicate style name of family " << static_cast<int>(nFamily) << ": \"" << rName << "\"");
1409 
1410 }
1411 
GetStyleDisplayName(XmlStyleFamily nFamily,const OUString & rName) const1412 OUString SvXMLImport::GetStyleDisplayName( XmlStyleFamily nFamily,
1413                                            const OUString& rName ) const
1414 {
1415     OUString sName( rName );
1416     if( mpStyleMap.is() && !rName.isEmpty() )
1417     {
1418         StyleMap::key_type aKey( nFamily, rName );
1419         StyleMap::const_iterator aIter = mpStyleMap->find( aKey );
1420         if( aIter != mpStyleMap->end() )
1421             sName = (*aIter).second;
1422     }
1423     return sName;
1424 }
1425 
SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue> &)1426 void SvXMLImport::SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
1427 {
1428 }
1429 
SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue> &)1430 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
1431 {
1432 }
1433 
SetDocumentSpecificSettings(const OUString &,const uno::Sequence<beans::PropertyValue> &)1434 void SvXMLImport::SetDocumentSpecificSettings(const OUString&, const uno::Sequence<beans::PropertyValue>&)
1435 {
1436 }
1437 
GetProgressBarHelper()1438 ProgressBarHelper*  SvXMLImport::GetProgressBarHelper()
1439 {
1440     if (!mpProgressBarHelper)
1441     {
1442         mpProgressBarHelper = std::make_unique<ProgressBarHelper>(mxStatusIndicator, false);
1443 
1444         if (mxImportInfo.is())
1445         {
1446             uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
1447             if (xPropertySetInfo.is())
1448             {
1449                 OUString sProgressRange(XML_PROGRESSRANGE);
1450                 OUString sProgressMax(XML_PROGRESSMAX);
1451                 OUString sProgressCurrent(XML_PROGRESSCURRENT);
1452                 OUString sRepeat(XML_PROGRESSREPEAT);
1453                 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
1454                     xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
1455                     xPropertySetInfo->hasPropertyByName(sProgressRange))
1456                 {
1457                     uno::Any aAny;
1458                     sal_Int32 nProgressMax(0);
1459                     sal_Int32 nProgressCurrent(0);
1460                     sal_Int32 nProgressRange(0);
1461                     aAny = mxImportInfo->getPropertyValue(sProgressRange);
1462                     if (aAny >>= nProgressRange)
1463                         mpProgressBarHelper->SetRange(nProgressRange);
1464                     aAny = mxImportInfo->getPropertyValue(sProgressMax);
1465                     if (aAny >>= nProgressMax)
1466                         mpProgressBarHelper->SetReference(nProgressMax);
1467                     aAny = mxImportInfo->getPropertyValue(sProgressCurrent);
1468                     if (aAny >>= nProgressCurrent)
1469                         mpProgressBarHelper->SetValue(nProgressCurrent);
1470                 }
1471                 if (xPropertySetInfo->hasPropertyByName(sRepeat))
1472                 {
1473                     uno::Any aAny = mxImportInfo->getPropertyValue(sRepeat);
1474                     if (aAny.getValueType() == cppu::UnoType<bool>::get())
1475                         mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
1476                     else {
1477                         SAL_WARN( "xmloff.core", "why is it no boolean?" );
1478                     }
1479                 }
1480             }
1481         }
1482     }
1483     return mpProgressBarHelper.get();
1484 }
1485 
AddNumberStyle(sal_Int32 nKey,const OUString & rName)1486 void SvXMLImport::AddNumberStyle(sal_Int32 nKey, const OUString& rName)
1487 {
1488     if (!mxNumberStyles.is())
1489         mxNumberStyles.set( comphelper::NameContainer_createInstance( ::cppu::UnoType<sal_Int32>::get()) );
1490     if (mxNumberStyles.is())
1491     {
1492         try
1493         {
1494             mxNumberStyles->insertByName(rName, Any(nKey));
1495         }
1496         catch ( uno::Exception& )
1497         {
1498             DBG_UNHANDLED_EXCEPTION( "xmloff.core", "Numberformat could not be inserted");
1499         }
1500     }
1501     else {
1502         SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1503     }
1504 }
1505 
GetEventImport()1506 XMLEventImportHelper& SvXMLImport::GetEventImport()
1507 {
1508     if (!mpEventImportHelper)
1509     {
1510         // construct event helper and register StarBasic handler and standard
1511         // event tables
1512         mpEventImportHelper = std::make_unique<XMLEventImportHelper>();
1513         const OUString& sStarBasic(GetXMLToken(XML_STARBASIC));
1514         mpEventImportHelper->RegisterFactory(sStarBasic,
1515                                             std::make_unique<XMLStarBasicContextFactory>());
1516         const OUString& sScript(GetXMLToken(XML_SCRIPT));
1517         mpEventImportHelper->RegisterFactory(sScript,
1518                                             std::make_unique<XMLScriptContextFactory>());
1519         mpEventImportHelper->AddTranslationTable(aStandardEventTable);
1520 
1521         // register StarBasic event handler with capitalized spelling
1522         mpEventImportHelper->RegisterFactory("StarBasic",
1523                                             std::make_unique<XMLStarBasicContextFactory>());
1524     }
1525 
1526     return *mpEventImportHelper;
1527 }
1528 
SetFontDecls(XMLFontStylesContext * pFontDecls)1529 void SvXMLImport::SetFontDecls( XMLFontStylesContext *pFontDecls )
1530 {
1531     if (mxFontDecls.is())
1532         mxFontDecls->dispose();
1533     mxFontDecls = pFontDecls;
1534 }
1535 
SetStyles(SvXMLStylesContext * pStyles)1536 void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
1537 {
1538     if (mxStyles.is())
1539         mxStyles->dispose();
1540     mxStyles = pStyles;
1541 }
1542 
SetAutoStyles(SvXMLStylesContext * pAutoStyles)1543 void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
1544 {
1545     if (pAutoStyles && mxNumberStyles.is())
1546     {
1547         uno::Reference<xml::sax::XFastAttributeList> xAttrList = new sax_fastparser::FastAttributeList(nullptr);
1548         const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames();
1549         for (const auto& name : aStyleNames)
1550         {
1551             uno::Any aAny(mxNumberStyles->getByName(name));
1552             sal_Int32 nKey(0);
1553             if (aAny >>= nKey)
1554             {
1555                 SvXMLStyleContext* pContext = new SvXMLNumFormatContext(
1556                     *this, name, xAttrList, nKey,
1557                     GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles);
1558                 pAutoStyles->AddStyle(*pContext);
1559             }
1560         }
1561     }
1562     if (mxAutoStyles.is())
1563         mxAutoStyles->dispose();
1564     mxAutoStyles = pAutoStyles;
1565     GetTextImport()->SetAutoStyles( pAutoStyles );
1566     GetShapeImport()->SetAutoStylesContext( pAutoStyles );
1567     GetChartImport()->SetAutoStylesContext( pAutoStyles );
1568     GetFormImport()->setAutoStyleContext( pAutoStyles );
1569 }
1570 
SetMasterStyles(SvXMLStylesContext * pMasterStyles)1571 void SvXMLImport::SetMasterStyles( SvXMLStylesContext *pMasterStyles )
1572 {
1573     if (mxMasterStyles.is())
1574         mxMasterStyles->dispose();
1575     mxMasterStyles = pMasterStyles;
1576 }
1577 
GetFontDecls()1578 XMLFontStylesContext *SvXMLImport::GetFontDecls()
1579 {
1580     return mxFontDecls.get();
1581 }
1582 
GetStyles()1583 SvXMLStylesContext *SvXMLImport::GetStyles()
1584 {
1585     return mxStyles.get();
1586 }
1587 
GetAutoStyles()1588 SvXMLStylesContext *SvXMLImport::GetAutoStyles()
1589 {
1590     return mxAutoStyles.get();
1591 }
1592 
GetFontDecls() const1593 const XMLFontStylesContext *SvXMLImport::GetFontDecls() const
1594 {
1595     return mxFontDecls.get();
1596 }
1597 
GetStyles() const1598 const SvXMLStylesContext *SvXMLImport::GetStyles() const
1599 {
1600     return mxStyles.get();
1601 }
1602 
GetAutoStyles() const1603 const SvXMLStylesContext *SvXMLImport::GetAutoStyles() const
1604 {
1605     return mxAutoStyles.get();
1606 }
1607 
GetAbsoluteReference(const OUString & rValue) const1608 OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue) const
1609 {
1610     if( rValue.isEmpty() || rValue[0] == '#' )
1611         return rValue;
1612 
1613     INetURLObject aAbsURL;
1614     if( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
1615         return aAbsURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
1616     else
1617         return rValue;
1618 }
1619 
IsODFVersionConsistent(const OUString & aODFVersion)1620 bool SvXMLImport::IsODFVersionConsistent( const OUString& aODFVersion )
1621 {
1622     // the check returns sal_False only if the storage version could be retrieved
1623     bool bResult = true;
1624 
1625     if ( !aODFVersion.isEmpty() && aODFVersion.compareTo( u"" ODFVER_012_TEXT ) >= 0 )
1626     {
1627         // check the consistency only for the ODF1.2 and later ( according to content.xml )
1628         // manifest.xml might have no version, it should be checked here and the correct version should be set
1629         try
1630         {   // don't use getDocumentStorage(), it's temporary and latest version
1631             uno::Reference<embed::XStorage> const xStor(GetSourceStorage());
1632             uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW );
1633 
1634             // the check should be done only for OASIS format
1635             if (!IsOOoXML())
1636             {
1637                 bool bRepairPackage = false;
1638                 try
1639                 {
1640                     xStorProps->getPropertyValue( "RepairPackage" )
1641                         >>= bRepairPackage;
1642                 } catch ( uno::Exception& )
1643                 {}
1644 
1645                 // check only if not in Repair mode
1646                 if ( !bRepairPackage )
1647                 {
1648                     OUString aStorVersion;
1649                     xStorProps->getPropertyValue( "Version" )
1650                         >>= aStorVersion;
1651 
1652                     // if the storage version is set in manifest.xml, it must be the same as in content.xml
1653                     // if not, set it explicitly to be used further ( it will work even for readonly storage )
1654                     // This workaround is not nice, but I see no other way to handle it, since there are
1655                     // ODF1.2 documents without version in manifest.xml
1656                     if ( !aStorVersion.isEmpty() )
1657                         bResult = aODFVersion == aStorVersion;
1658                     else
1659                         xStorProps->setPropertyValue( "Version",
1660                                                       uno::makeAny( aODFVersion ) );
1661 
1662                     if ( bResult )
1663                     {
1664                         bool bInconsistent = false;
1665                         xStorProps->getPropertyValue( "IsInconsistent" )
1666                             >>= bInconsistent;
1667                         bResult = !bInconsistent;
1668                     }
1669                 }
1670             }
1671         }
1672         catch( uno::Exception& )
1673         {}
1674     }
1675 
1676     return bResult;
1677 }
1678 
CreateNumberFormatsSupplier_()1679 void SvXMLImport::CreateNumberFormatsSupplier_()
1680 {
1681     SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core", "number formats supplier already exists!" );
1682     if(mxModel.is())
1683         mxNumberFormatsSupplier =
1684             uno::Reference< util::XNumberFormatsSupplier> (mxModel, uno::UNO_QUERY);
1685 }
1686 
CreateDataStylesImport_()1687 void SvXMLImport::CreateDataStylesImport_()
1688 {
1689     SAL_WARN_IF( bool(mpNumImport), "xmloff.core", "data styles import already exists!" );
1690     uno::Reference<util::XNumberFormatsSupplier> xNum =
1691         GetNumberFormatsSupplier();
1692     if ( xNum.is() )
1693         mpNumImport = std::make_unique<SvXMLNumFmtHelper>(xNum, GetComponentContext() );
1694 }
1695 
ConvStarBatsCharToStarSymbol(sal_Unicode c)1696 sal_Unicode SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c )
1697 {
1698     sal_Unicode cNew = c;
1699     if( !mpImpl->hBatsFontConv )
1700     {
1701         mpImpl->hBatsFontConv = CreateFontToSubsFontConverter( "StarBats",
1702                  FontToSubsFontFlags::IMPORT );
1703         SAL_WARN_IF( !mpImpl->hBatsFontConv, "xmloff.core", "Got no symbol font converter" );
1704     }
1705     if( mpImpl->hBatsFontConv )
1706     {
1707         cNew = ConvertFontToSubsFontChar( mpImpl->hBatsFontConv, c );
1708     }
1709 
1710     return cNew;
1711 }
1712 
ConvStarMathCharToStarSymbol(sal_Unicode c)1713 sal_Unicode SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c )
1714 {
1715     sal_Unicode cNew = c;
1716     if( !mpImpl->hMathFontConv )
1717     {
1718         mpImpl->hMathFontConv = CreateFontToSubsFontConverter( "StarMath",
1719                  FontToSubsFontFlags::IMPORT );
1720         SAL_WARN_IF( !mpImpl->hMathFontConv, "xmloff.core", "Got no symbol font converter" );
1721     }
1722     if( mpImpl->hMathFontConv )
1723     {
1724         cNew = ConvertFontToSubsFontChar( mpImpl->hMathFontConv, c );
1725     }
1726 
1727     return cNew;
1728 }
1729 
SetError(sal_Int32 nId,const Sequence<OUString> & rMsgParams,const OUString & rExceptionMessage,const Reference<xml::sax::XLocator> & rLocator)1730 void SvXMLImport::SetError(
1731     sal_Int32 nId,
1732     const Sequence<OUString>& rMsgParams,
1733     const OUString& rExceptionMessage,
1734     const Reference<xml::sax::XLocator>& rLocator )
1735 {
1736     // create error list on demand
1737     if ( !mpXMLErrors )
1738         mpXMLErrors = std::make_unique<XMLErrors>();
1739 
1740     // save error information
1741     // use document locator (if none supplied)
1742     mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage,
1743                            rLocator.is() ? rLocator : mxLocator );
1744 }
1745 
SetError(sal_Int32 nId,const Sequence<OUString> & rMsgParams)1746 void SvXMLImport::SetError(
1747     sal_Int32 nId,
1748     const Sequence<OUString>& rMsgParams)
1749 {
1750     SetError( nId, rMsgParams, "", nullptr );
1751 }
1752 
SetError(sal_Int32 nId)1753 void SvXMLImport::SetError(
1754     sal_Int32 nId)
1755 {
1756     Sequence<OUString> aSeq(0);
1757     SetError( nId, aSeq );
1758 }
1759 
SetError(sal_Int32 nId,const OUString & rMsg1)1760 void SvXMLImport::SetError(
1761     sal_Int32 nId,
1762     const OUString& rMsg1)
1763 {
1764     Sequence<OUString> aSeq { rMsg1 };
1765     SetError( nId, aSeq );
1766 }
1767 
DisposingModel()1768 void SvXMLImport::DisposingModel()
1769 {
1770     if( mxFontDecls.is() )
1771         mxFontDecls->dispose();
1772     if( mxStyles.is() )
1773         mxStyles->dispose();
1774     if( mxAutoStyles.is() )
1775         mxAutoStyles->dispose();
1776     if( mxMasterStyles.is() )
1777         mxMasterStyles->dispose();
1778 
1779     mxModel.set(nullptr);
1780     mxEventListener.set(nullptr);
1781 }
1782 
getInterfaceToIdentifierMapper()1783 ::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLImport::getInterfaceToIdentifierMapper()
1784 {
1785     return mpImpl->maInterfaceToIdentifierMapper;
1786 }
1787 
1788 uno::Reference< uno::XComponentContext > const &
GetComponentContext() const1789 SvXMLImport::GetComponentContext() const
1790 {
1791     return mpImpl->mxComponentContext;
1792 }
1793 
GetBaseURL() const1794 OUString SvXMLImport::GetBaseURL() const
1795 {
1796     return mpImpl->aBaseURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1797 }
1798 
GetDocumentBase() const1799 OUString SvXMLImport::GetDocumentBase() const
1800 {
1801     return mpImpl->aDocBase.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1802 }
1803 
1804 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
IsShapePositionInHoriL2R() const1805 bool SvXMLImport::IsShapePositionInHoriL2R() const
1806 {
1807     return mpImpl->mbShapePositionInHoriL2R;
1808 }
1809 
IsTextDocInOOoFileFormat() const1810 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1811 {
1812     return mpImpl->mbTextDocInOOoFileFormat;
1813 }
1814 
initXForms()1815 void SvXMLImport::initXForms()
1816 {
1817     // dummy method; to be implemented by derived classes supporting XForms
1818 }
1819 
getBuildIds(sal_Int32 & rUPD,sal_Int32 & rBuild) const1820 bool SvXMLImport::getBuildIds( sal_Int32& rUPD, sal_Int32& rBuild ) const
1821 {
1822     bool bRet = false;
1823     OUString const aBuildId(getBuildIdsProperty(mxImportInfo));
1824     if (!aBuildId.isEmpty())
1825     {
1826         sal_Int32 nIndex = aBuildId.indexOf('$');
1827         if (nIndex != -1)
1828         {
1829             rUPD = aBuildId.copy( 0, nIndex ).toInt32();
1830             sal_Int32 nIndexEnd = aBuildId.indexOf(';', nIndex);
1831             rBuild = (nIndexEnd == -1)
1832                 ? aBuildId.copy(nIndex + 1).toInt32()
1833                 : aBuildId.copy(nIndex + 1, nIndexEnd - nIndex - 1).toInt32();
1834             bRet = true;
1835         }
1836     }
1837     return bRet;
1838 }
1839 
getGeneratorVersion() const1840 sal_uInt16 SvXMLImport::getGeneratorVersion() const
1841 {
1842     // --> ORW
1843     return mpImpl->getGeneratorVersion( *this );
1844     // <--
1845 }
1846 
isGeneratorVersionOlderThan(sal_uInt16 const nOOoVersion,sal_uInt16 const nLOVersion)1847 bool SvXMLImport::isGeneratorVersionOlderThan(
1848         sal_uInt16 const nOOoVersion, sal_uInt16 const nLOVersion)
1849 {
1850     assert( (nLOVersion  & LO_flag));
1851     assert(!(nOOoVersion & LO_flag));
1852     const sal_uInt16 nGeneratorVersion(getGeneratorVersion());
1853     return (nGeneratorVersion & LO_flag)
1854         ?   nGeneratorVersion < nLOVersion
1855         :   nGeneratorVersion < nOOoVersion;
1856 }
1857 
1858 
GetODFVersion() const1859 OUString SvXMLImport::GetODFVersion() const
1860 {
1861     return mpImpl->mxODFVersion ? *mpImpl->mxODFVersion : OUString();
1862 }
1863 
IsOOoXML() const1864 bool SvXMLImport::IsOOoXML() const
1865 {
1866     return mpImpl->mbIsOOoXML;
1867 }
1868 
1869 // xml:id for RDF metadata
SetXmlId(uno::Reference<uno::XInterface> const & i_xIfc,OUString const & i_rXmlId)1870 void SvXMLImport::SetXmlId(uno::Reference<uno::XInterface> const & i_xIfc,
1871     OUString const & i_rXmlId)
1872 {
1873     if (i_rXmlId.isEmpty())
1874         return;
1875 
1876     try {
1877         const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
1878             uno::UNO_QUERY);
1879 //FIXME: not yet
1880         if (xMeta.is()) {
1881             const beans::StringPair mdref( mpImpl->mStreamName, i_rXmlId );
1882             try {
1883                 xMeta->setMetadataReference(mdref);
1884             } catch (lang::IllegalArgumentException &) {
1885                 // probably duplicate; ignore
1886                 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1887             }
1888         }
1889     } catch (uno::Exception &) {
1890         TOOLS_WARN_EXCEPTION("xmloff.core","SvXMLImport::SetXmlId");
1891     }
1892 }
1893 
1894 ::xmloff::RDFaImportHelper &
GetRDFaImportHelper()1895 SvXMLImport::GetRDFaImportHelper()
1896 {
1897     if (!mpImpl->mpRDFaHelper)
1898     {
1899         mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaImportHelper(*this) );
1900     }
1901     return *mpImpl->mpRDFaHelper;
1902 }
1903 
1904 void
AddRDFa(const uno::Reference<rdf::XMetadatable> & i_xObject,OUString const & i_rAbout,OUString const & i_rProperty,OUString const & i_rContent,OUString const & i_rDatatype)1905 SvXMLImport::AddRDFa(const uno::Reference<rdf::XMetadatable>& i_xObject,
1906     OUString const & i_rAbout,
1907     OUString const & i_rProperty,
1908     OUString const & i_rContent,
1909     OUString const & i_rDatatype)
1910 {
1911     // N.B.: we only get called if i_xObject had xhtml:about attribute
1912     // (an empty attribute value is valid)
1913     ::xmloff::RDFaImportHelper & rRDFaHelper( GetRDFaImportHelper() );
1914     rRDFaHelper.ParseAndAddRDFa(i_xObject,
1915         i_rAbout, i_rProperty, i_rContent, i_rDatatype);
1916 }
1917 
embeddedFontAlreadyProcessed(const OUString & url)1918 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString& url )
1919 {
1920     if( embeddedFontUrlsKnown.count( url ) != 0 )
1921         return true;
1922     embeddedFontUrlsKnown.insert( url );
1923     return false;
1924 }
1925 
getNameFromToken(sal_Int32 nToken)1926 const OUString & SvXMLImport::getNameFromToken( sal_Int32 nToken )
1927 {
1928     return xTokenHandler->getIdentifier( nToken & TOKEN_MASK );
1929 }
1930 
getPrefixAndNameFromToken(sal_Int32 nToken)1931 OUString SvXMLImport::getPrefixAndNameFromToken( sal_Int32 nToken )
1932 {
1933     OUString rv;
1934     sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
1935     auto aIter( aNamespaceMap.find( nNamespaceToken ) );
1936     if( aIter != aNamespaceMap.end() )
1937         rv = (*aIter).second.second + " " + aIter->second.first + ":";
1938     return rv + xTokenHandler->getIdentifier( nToken & TOKEN_MASK );
1939 }
1940 
getNamespacePrefixFromToken(sal_Int32 nToken,const SvXMLNamespaceMap * pMap)1941 OUString SvXMLImport::getNamespacePrefixFromToken(sal_Int32 nToken, const SvXMLNamespaceMap* pMap)
1942 {
1943     sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
1944     auto aIter( aNamespaceMap.find( nNamespaceToken ) );
1945     if( aIter != aNamespaceMap.end() )
1946     {
1947         if (pMap)
1948         {
1949             OUString sRet = pMap->GetPrefixByKey(pMap->GetKeyByName((*aIter).second.second));
1950             if (!sRet.isEmpty())
1951                 return sRet;
1952         }
1953         return (*aIter).second.first;
1954     }
1955     else
1956         return OUString();
1957 }
1958 
getNamespaceURIFromToken(sal_Int32 nToken)1959 OUString SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken )
1960 {
1961     sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
1962     auto aIter( aNamespaceMap.find( nNamespaceToken ) );
1963     if( aIter != aNamespaceMap.end() )
1964         return (*aIter).second.second;
1965     else
1966         return OUString();
1967 }
1968 
getNamespacePrefixFromURI(const OUString & rURI)1969 OUString SvXMLImport::getNamespacePrefixFromURI( const OUString& rURI )
1970 {
1971     auto aIter( aNamespaceURIPrefixMap.find(rURI) );
1972     if( aIter != aNamespaceURIPrefixMap.end() )
1973         return (*aIter).second;
1974     else
1975         return OUString();
1976 }
1977 
getTokenFromName(const OUString & rName)1978 sal_Int32 SvXMLImport::getTokenFromName( const OUString& rName )
1979 {
1980     Sequence< sal_Int8 > aLocalNameSeq( reinterpret_cast<sal_Int8 const *>(
1981         OUStringToOString( rName, RTL_TEXTENCODING_UTF8 ).getStr()), rName.getLength() );
1982     return xTokenHandler->getTokenFromUTF8( aLocalNameSeq );
1983 }
1984 
initializeNamespaceMaps()1985 void SvXMLImport::initializeNamespaceMaps()
1986 {
1987     auto mapTokenToNamespace = [&]( sal_Int32 nToken, sal_Int32 nPrefix, sal_Int32 nNamespace )
1988     {
1989         if ( nToken >= 0 )
1990         {
1991             const OUString& sNamespace = GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) );
1992             const OUString& sPrefix = GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) );
1993             assert( aNamespaceMap.find(nToken +1) == aNamespaceMap.end() && "cannot map two namespaces to the same token here");
1994             aNamespaceMap[ nToken + 1 ] = std::make_pair( sPrefix, sNamespace );
1995             aNamespaceURIPrefixMap.emplace( sNamespace, sPrefix );
1996         }
1997     };
1998 
1999     mapTokenToNamespace( XML_NAMESPACE_XML,              XML_XML,              XML_N_XML              ); // implicit "xml" namespace prefix
2000     mapTokenToNamespace( XML_NAMESPACE_OFFICE,           XML_NP_OFFICE,        XML_N_OFFICE           );
2001     mapTokenToNamespace( XML_NAMESPACE_OFFICE_SO52,      XML_NP_OFFICE,        XML_N_OFFICE_OLD       );
2002     mapTokenToNamespace( XML_NAMESPACE_OFFICE_OOO,       XML_NP_OFFICE,        XML_N_OFFICE_OOO       );
2003     mapTokenToNamespace( XML_NAMESPACE_STYLE,            XML_NP_STYLE,         XML_N_STYLE            );
2004     mapTokenToNamespace( XML_NAMESPACE_STYLE_SO52,       XML_NP_STYLE,         XML_N_STYLE_OLD        );
2005     mapTokenToNamespace( XML_NAMESPACE_STYLE_OOO,        XML_NP_STYLE,         XML_N_STYLE_OOO        );
2006     mapTokenToNamespace( XML_NAMESPACE_TEXT,             XML_NP_TEXT,          XML_N_TEXT             );
2007     mapTokenToNamespace( XML_NAMESPACE_TEXT_SO52,        XML_NP_TEXT,          XML_N_TEXT_OLD         );
2008     mapTokenToNamespace( XML_NAMESPACE_TEXT_OOO,         XML_NP_TEXT,          XML_N_TEXT_OOO         );
2009     mapTokenToNamespace( XML_NAMESPACE_TABLE,            XML_NP_TABLE,         XML_N_TABLE            );
2010     mapTokenToNamespace( XML_NAMESPACE_TABLE_SO52,       XML_NP_TABLE,         XML_N_TABLE_OLD        );
2011     mapTokenToNamespace( XML_NAMESPACE_TABLE_OOO,        XML_NP_TABLE,         XML_N_TABLE_OOO        );
2012     mapTokenToNamespace( XML_NAMESPACE_DRAW,             XML_NP_DRAW,          XML_N_DRAW             );
2013     mapTokenToNamespace( XML_NAMESPACE_DRAW_SO52,        XML_NP_DRAW,          XML_N_DRAW_OLD         );
2014     mapTokenToNamespace( XML_NAMESPACE_DRAW_OOO,         XML_NP_DRAW,          XML_N_DRAW_OOO         );
2015     mapTokenToNamespace( XML_NAMESPACE_FO,               XML_NP_FO,            XML_N_FO               );
2016     mapTokenToNamespace( XML_NAMESPACE_FO_SO52,          XML_NP_FO,            XML_N_FO_OLD           );
2017     mapTokenToNamespace( XML_NAMESPACE_FO_COMPAT,        XML_NP_FO,            XML_N_FO_COMPAT        );
2018     mapTokenToNamespace( XML_NAMESPACE_XLINK,            XML_NP_XLINK,         XML_N_XLINK            );
2019     mapTokenToNamespace( XML_NAMESPACE_XLINK_SO52,       XML_NP_XLINK,         XML_N_XLINK_OLD        );
2020     mapTokenToNamespace( XML_NAMESPACE_DC,               XML_NP_DC,            XML_N_DC               );
2021     mapTokenToNamespace( XML_NAMESPACE_META,             XML_NP_META,          XML_N_META             );
2022     mapTokenToNamespace( XML_NAMESPACE_META_SO52,        XML_NP_META,          XML_N_META_OLD         );
2023     mapTokenToNamespace( XML_NAMESPACE_META_OOO,         XML_NP_META,          XML_N_META_OOO         );
2024     mapTokenToNamespace( XML_NAMESPACE_NUMBER,           XML_NP_NUMBER,        XML_N_NUMBER           );
2025     mapTokenToNamespace( XML_NAMESPACE_NUMBER_SO52,      XML_NP_NUMBER,        XML_N_NUMBER_OLD       );
2026     mapTokenToNamespace( XML_NAMESPACE_NUMBER_OOO,       XML_NP_NUMBER,        XML_N_NUMBER_OOO       );
2027     mapTokenToNamespace( XML_NAMESPACE_PRESENTATION,     XML_NP_PRESENTATION,  XML_N_PRESENTATION     );
2028     mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_SO52,XML_NP_PRESENTATION,  XML_N_PRESENTATION_OLD );
2029     mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OOO, XML_NP_PRESENTATION,  XML_N_PRESENTATION_OOO );
2030     mapTokenToNamespace( XML_NAMESPACE_PRESENTATION_OASIS, XML_NP_PRESENTATION, XML_N_PRESENTATION_OASIS );
2031     mapTokenToNamespace( XML_NAMESPACE_SVG,              XML_NP_SVG,           XML_N_SVG              );
2032     mapTokenToNamespace( XML_NAMESPACE_SVG_COMPAT,       XML_NP_SVG,           XML_N_SVG_COMPAT       );
2033     mapTokenToNamespace( XML_NAMESPACE_CHART,            XML_NP_CHART,         XML_N_CHART            );
2034     mapTokenToNamespace( XML_NAMESPACE_CHART_SO52,       XML_NP_CHART,         XML_N_CHART_OLD        );
2035     mapTokenToNamespace( XML_NAMESPACE_CHART_OOO,        XML_NP_CHART,         XML_N_CHART_OOO        );
2036     mapTokenToNamespace( XML_NAMESPACE_DR3D,             XML_NP_DR3D,          XML_N_DR3D             );
2037     mapTokenToNamespace( XML_NAMESPACE_DR3D_OOO,         XML_NP_DR3D,          XML_N_DR3D_OOO         );
2038     mapTokenToNamespace( XML_NAMESPACE_MATH,             XML_NP_MATH,          XML_N_MATH             );
2039     mapTokenToNamespace( XML_NAMESPACE_VERSIONS_LIST,    XML_NP_VERSIONS_LIST, XML_N_VERSIONS_LIST    );
2040     mapTokenToNamespace( XML_NAMESPACE_FORM,             XML_NP_FORM,          XML_N_FORM             );
2041     mapTokenToNamespace( XML_NAMESPACE_FORM_OOO,         XML_NP_FORM,          XML_N_FORM_OOO         );
2042     mapTokenToNamespace( XML_NAMESPACE_SCRIPT,           XML_NP_SCRIPT,        XML_N_SCRIPT           );
2043     mapTokenToNamespace( XML_NAMESPACE_SCRIPT_OOO,       XML_NP_SCRIPT,        XML_N_SCRIPT_OOO       );
2044     mapTokenToNamespace( XML_NAMESPACE_BLOCKLIST,        XML_NP_BLOCK_LIST,    XML_N_BLOCK_LIST       );
2045     mapTokenToNamespace( XML_NAMESPACE_CONFIG,           XML_NP_CONFIG,        XML_N_CONFIG           );
2046     mapTokenToNamespace( XML_NAMESPACE_CONFIG_OOO,       XML_NP_CONFIG,        XML_N_CONFIG_OOO       );
2047     mapTokenToNamespace( XML_NAMESPACE_OOO,              XML_NP_OOO,           XML_N_OOO              );
2048     mapTokenToNamespace( XML_NAMESPACE_OOOW,             XML_NP_OOOW,          XML_N_OOOW             );
2049     mapTokenToNamespace( XML_NAMESPACE_OOOC,             XML_NP_OOOC,          XML_N_OOOC             );
2050     mapTokenToNamespace( XML_NAMESPACE_DOM,              XML_NP_DOM,           XML_N_DOM              );
2051     mapTokenToNamespace( XML_NAMESPACE_DB,               XML_NP_DB,            XML_N_DB               );
2052     mapTokenToNamespace( XML_NAMESPACE_DB_OASIS,         XML_NP_DB,            XML_N_DB_OASIS         );
2053     mapTokenToNamespace( XML_NAMESPACE_DLG,              XML_NP_DLG,           XML_N_DLG              );
2054     mapTokenToNamespace( XML_NAMESPACE_XFORMS,           XML_NP_XFORMS_1_0,    XML_N_XFORMS_1_0       );
2055     mapTokenToNamespace( XML_NAMESPACE_XSD,              XML_NP_XSD,           XML_N_XSD              );
2056     mapTokenToNamespace( XML_NAMESPACE_XSI,              XML_NP_XSI,           XML_N_XSI              );
2057     mapTokenToNamespace( XML_NAMESPACE_SMIL,             XML_NP_SMIL,          XML_N_SMIL             );
2058     mapTokenToNamespace( XML_NAMESPACE_SMIL_SO52,        XML_NP_SMIL,          XML_N_SMIL_OLD         );
2059     mapTokenToNamespace( XML_NAMESPACE_SMIL_COMPAT,      XML_NP_SMIL,          XML_N_SMIL_COMPAT      );
2060     mapTokenToNamespace( XML_NAMESPACE_ANIMATION,        XML_NP_ANIMATION,     XML_N_ANIMATION        );
2061     mapTokenToNamespace( XML_NAMESPACE_ANIMATION_OOO,    XML_NP_ANIMATION,     XML_N_ANIMATION_OOO    );
2062     mapTokenToNamespace( XML_NAMESPACE_REPORT,           XML_NP_RPT,           XML_N_RPT              );
2063     mapTokenToNamespace( XML_NAMESPACE_REPORT_OASIS,     XML_NP_RPT,           XML_N_RPT_OASIS        );
2064     mapTokenToNamespace( XML_NAMESPACE_OF,               XML_NP_OF,            XML_N_OF               );
2065     mapTokenToNamespace( XML_NAMESPACE_XHTML,            XML_NP_XHTML,         XML_N_XHTML            );
2066     mapTokenToNamespace( XML_NAMESPACE_GRDDL,            XML_NP_GRDDL,         XML_N_GRDDL            );
2067     mapTokenToNamespace( XML_NAMESPACE_OFFICE_EXT,       XML_NP_OFFICE_EXT,    XML_N_OFFICE_EXT       );
2068     mapTokenToNamespace( XML_NAMESPACE_TABLE_EXT,        XML_NP_TABLE_EXT,     XML_N_TABLE_EXT        );
2069     mapTokenToNamespace( XML_NAMESPACE_CHART_EXT,        XML_NP_CHART_EXT,     XML_N_CHART_EXT        );
2070     mapTokenToNamespace( XML_NAMESPACE_DRAW_EXT,         XML_NP_DRAW_EXT,      XML_N_DRAW_EXT         );
2071     mapTokenToNamespace( XML_NAMESPACE_CALC_EXT,         XML_NP_CALC_EXT,      XML_N_CALC_EXT         );
2072     mapTokenToNamespace( XML_NAMESPACE_LO_EXT,           XML_NP_LO_EXT,        XML_N_LO_EXT           );
2073     mapTokenToNamespace( XML_NAMESPACE_CSS3TEXT,         XML_NP_CSS3TEXT,      XML_N_CSS3TEXT         );
2074     mapTokenToNamespace( XML_NAMESPACE_FIELD,            XML_NP_FIELD,         XML_N_FIELD            );
2075     mapTokenToNamespace( XML_NAMESPACE_FORMX,            XML_NP_FORMX,         XML_N_FORMX            );
2076 }
2077 
registerNamespaces()2078 void SvXMLImport::registerNamespaces()
2079 {
2080     for( auto const &aNamespaceEntry : aNamespaceMap )
2081     {
2082         // aNamespaceMap = { Token : ( NamespacePrefix, NamespaceURI ) }
2083         registerNamespace( aNamespaceEntry.second.second, aNamespaceEntry.first << NMSP_SHIFT );
2084     }
2085 }
2086 
NotifyMacroEventRead()2087 void SvXMLImport::NotifyMacroEventRead()
2088 {
2089     if (mbNotifyMacroEventRead)
2090         return;
2091 
2092     comphelper::DocumentInfo::notifyMacroEventRead(mxModel);
2093 
2094     mbNotifyMacroEventRead = true;
2095 }
2096 
SvXMLImportFastNamespaceHandler()2097 SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler()
2098 {
2099 }
2100 
addNSDeclAttributes(rtl::Reference<comphelper::AttributeList> const & rAttrList)2101 void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference < comphelper::AttributeList > const & rAttrList )
2102 {
2103     for(const auto& aNamespaceDefine : m_aNamespaceDefines)
2104     {
2105         OUString& rPrefix = aNamespaceDefine->m_aPrefix;
2106         OUString& rNamespaceURI = aNamespaceDefine->m_aNamespaceURI;
2107         OUString sDecl;
2108         if ( rPrefix.isEmpty() )
2109             sDecl = "xmlns";
2110         else
2111             sDecl = "xmlns:" + rPrefix;
2112         rAttrList->AddAttribute( sDecl, "CDATA", rNamespaceURI );
2113     }
2114     m_aNamespaceDefines.clear();
2115 }
2116 
registerNamespace(const OUString & rNamespacePrefix,const OUString & rNamespaceURI)2117 void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI )
2118 {
2119     // Elements with default namespace parsed by FastParser have namespace prefix.
2120     // A default namespace needs to be registered with the prefix, to maintain the compatibility.
2121     if ( rNamespacePrefix.isEmpty() )
2122         m_aNamespaceDefines.push_back( std::make_unique<NamespaceDefine>(
2123                                     SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI ), rNamespaceURI) );
2124 
2125     m_aNamespaceDefines.push_back( std::make_unique<NamespaceDefine>(
2126                                     rNamespacePrefix, rNamespaceURI) );
2127 }
2128 
getNamespaceURI(const OUString &)2129 OUString SvXMLImportFastNamespaceHandler::getNamespaceURI( const OUString&/* rNamespacePrefix */ )
2130 {
2131     return OUString();
2132 }
2133 
SvXMLLegacyToFastDocHandler(const rtl::Reference<SvXMLImport> & rImport)2134 SvXMLLegacyToFastDocHandler::SvXMLLegacyToFastDocHandler( const rtl::Reference< SvXMLImport > & rImport )
2135 :   mrImport( rImport ),
2136     mxFastAttributes( new sax_fastparser::FastAttributeList( SvXMLImport::xTokenHandler.get() ) )
2137 {
2138 }
2139 
setTargetDocument(const uno::Reference<lang::XComponent> & xDoc)2140 void SAL_CALL SvXMLLegacyToFastDocHandler::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
2141 {
2142     mrImport->setTargetDocument( xDoc );
2143 }
2144 
startDocument()2145 void SAL_CALL SvXMLLegacyToFastDocHandler::startDocument()
2146 {
2147     mrImport->startDocument();
2148 }
2149 
endDocument()2150 void SAL_CALL SvXMLLegacyToFastDocHandler::endDocument()
2151 {
2152     mrImport->endDocument();
2153 }
2154 
startElement(const OUString & rName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2155 void SAL_CALL SvXMLLegacyToFastDocHandler::startElement( const OUString& rName,
2156                         const uno::Reference< xml::sax::XAttributeList >& xAttrList )
2157 {
2158     sal_uInt16 nDefaultNamespace = XML_NAMESPACE_UNKNOWN;
2159     if (!maDefaultNamespaces.empty())
2160         nDefaultNamespace = maDefaultNamespaces.top();
2161     SvXMLImport::processNSAttributes(mrImport->mpNamespaceMap, mrImport.get(), xAttrList);
2162     OUString aLocalName;
2163     sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
2164     sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName( aLocalName );
2165     mxFastAttributes->clear();
2166 
2167     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
2168     for( sal_Int16 i=0; i < nAttrCount; i++ )
2169     {
2170         const OUString& rAttrName = xAttrList->getNameByIndex( i );
2171         const OUString& rAttrValue = xAttrList->getValueByIndex( i );
2172         if (rAttrName == "xmlns")
2173         {
2174             sal_uInt16 nNamespaceKey = mrImport->mpNamespaceMap->GetKeyByName(rAttrValue);
2175             if (nNamespaceKey != XML_NAMESPACE_UNKNOWN)
2176             {
2177                 nDefaultNamespace = nNamespaceKey;
2178                 continue;
2179             }
2180             assert(false && "unknown namespace");
2181         }
2182         else if (rAttrName.indexOf(":") == -1 && nDefaultNamespace != XML_NAMESPACE_UNKNOWN)
2183         {
2184             auto const nToken = SvXMLImport::getTokenFromName(rAttrName);
2185             if (nToken == xmloff::XML_TOKEN_INVALID)
2186             {
2187                 mxFastAttributes->addUnknown(mrImport->mpNamespaceMap->GetNameByKey(nDefaultNamespace),
2188                     OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
2189                     OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2190             }
2191             else
2192             {
2193                 sal_Int32 const nAttr = NAMESPACE_TOKEN(nDefaultNamespace) | nToken;
2194                 mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2195             }
2196             continue;
2197         }
2198 
2199         OUString aLocalAttrName;
2200         OUString aNamespace;
2201         // don't add unknown namespaces to the map
2202         sal_uInt16 const nAttrPrefix = mrImport->mpNamespaceMap->GetKeyByQName(
2203                 rAttrName, nullptr, &aLocalAttrName, &aNamespace, SvXMLNamespaceMap::QNameMode::AttrValue);
2204         if( XML_NAMESPACE_XMLNS == nAttrPrefix )
2205             continue; // ignore
2206         auto const nToken = SvXMLImport::getTokenFromName(aLocalAttrName);
2207         if (XML_NAMESPACE_UNKNOWN == nAttrPrefix || nToken == xmloff::XML_TOKEN_INVALID)
2208         {
2209             mxFastAttributes->addUnknown(aNamespace,
2210                 OUStringToOString(rAttrName, RTL_TEXTENCODING_UTF8),
2211                 OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2212         }
2213         else
2214         {
2215             sal_Int32 const nAttr = NAMESPACE_TOKEN(nAttrPrefix) | nToken;
2216             mxFastAttributes->add(nAttr, OUStringToOString(rAttrValue, RTL_TEXTENCODING_UTF8));
2217         }
2218     }
2219     mrImport->startFastElement( mnElement, mxFastAttributes );
2220     maDefaultNamespaces.push(nDefaultNamespace);
2221 }
2222 
endElement(const OUString & rName)2223 void SAL_CALL SvXMLLegacyToFastDocHandler::endElement( const OUString& rName )
2224 {
2225     OUString aLocalName;
2226     sal_uInt16 nPrefix = mrImport->mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
2227     sal_Int32 mnElement = NAMESPACE_TOKEN( nPrefix ) | SvXMLImport::getTokenFromName(aLocalName);
2228     mrImport->endFastElement( mnElement );
2229     maDefaultNamespaces.pop();
2230 }
2231 
characters(const OUString & aChars)2232 void SAL_CALL SvXMLLegacyToFastDocHandler::characters( const OUString& aChars )
2233 {
2234     mrImport->characters( aChars );
2235 }
2236 
ignorableWhitespace(const OUString &)2237 void SAL_CALL SvXMLLegacyToFastDocHandler::ignorableWhitespace( const OUString& )
2238 {
2239 }
2240 
processingInstruction(const OUString & aTarget,const OUString & aData)2241 void SAL_CALL SvXMLLegacyToFastDocHandler::processingInstruction( const OUString& aTarget,
2242                                                                   const OUString& aData)
2243 {
2244     mrImport->processingInstruction( aTarget, aData );
2245 }
2246 
setDocumentLocator(const uno::Reference<xml::sax::XLocator> & rLocator)2247 void SAL_CALL SvXMLLegacyToFastDocHandler::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
2248 {
2249     mrImport->setDocumentLocator( rLocator );
2250 }
2251 
2252 
2253 
2254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2255