Bug Summary

File:home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
Warning:line 866, column 1
Potential leak of memory pointed to by 'aValue.pObj'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name OOXMLFastContextHandler.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/oox/generated -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/writerfilter/source -I /home/maarten/src/libreoffice/core/writerfilter/inc -I /home/maarten/src/libreoffice/core/writerfilter/source -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
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 <com/sun/star/beans/XPropertySet.hpp>
21#include <com/sun/star/text/RelOrientation.hpp>
22#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
23#include <com/sun/star/xml/sax/FastShapeContextHandler.hpp>
24#include <com/sun/star/xml/sax/SAXException.hpp>
25#include <ooxml/resourceids.hxx>
26#include <oox/mathml/import.hxx>
27#include <oox/token/namespaces.hxx>
28#include <sal/log.hxx>
29#include <comphelper/embeddedobjectcontainer.hxx>
30#include <cppuhelper/exc_hlp.hxx>
31#include <tools/globname.hxx>
32#include <comphelper/classids.hxx>
33#include <sfx2/sfxbasemodel.hxx>
34#include "OOXMLFastContextHandler.hxx"
35#include "OOXMLFactory.hxx"
36#include "Handler.hxx"
37#include <dmapper/PropertyIds.hxx>
38#include <comphelper/propertysequence.hxx>
39#include <comphelper/sequenceashashmap.hxx>
40
41const sal_Unicode uCR = 0xd;
42const sal_Unicode uFtnEdnRef = 0x2;
43const sal_Unicode uFtnEdnSep = 0x3;
44const sal_Unicode uTab = 0x9;
45const sal_Unicode uPgNum = 0x0;
46const sal_Unicode uNoBreakHyphen = 0x2011;
47const sal_Unicode uSoftHyphen = 0xAD;
48
49const sal_uInt8 cFtnEdnCont = 0x4;
50const sal_uInt8 cFieldLock = 0x8;
51
52namespace writerfilter::ooxml
53{
54using namespace ::com::sun::star;
55using namespace oox;
56using namespace ::std;
57using namespace ::com::sun::star::xml::sax;
58
59/*
60 class OOXMLFastContextHandler
61 */
62
63OOXMLFastContextHandler::OOXMLFastContextHandler
64(uno::Reference< uno::XComponentContext > const & context)
65: mpParent(nullptr),
66 mId(0),
67 mnDefine(0),
68 mnToken(oox::XML_TOKEN_COUNT),
69 mnMathJcVal(0),
70 mbIsMathPara(false),
71 mpStream(nullptr),
72 mnTableDepth(0),
73 inPositionV(false),
74 mbAllowInCell(true),
75 mbIsVMLfound(false),
76 m_xContext(context),
77 m_bDiscardChildren(false),
78 m_bTookChoice(false)
79{
80 if (!mpParserState)
81 mpParserState = new OOXMLParserState();
82
83 mpParserState->incContextCount();
84}
85
86OOXMLFastContextHandler::OOXMLFastContextHandler(OOXMLFastContextHandler * pContext)
87: cppu::WeakImplHelper<xml::sax::XFastContextHandler>(),
88 mpParent(pContext),
89 mId(0),
90 mnDefine(0),
91 mnToken(oox::XML_TOKEN_COUNT),
92 mnMathJcVal(pContext->mnMathJcVal),
93 mbIsMathPara(pContext->mbIsMathPara),
94 mpStream(pContext->mpStream),
95 mpParserState(pContext->mpParserState),
96 mnTableDepth(pContext->mnTableDepth),
97 inPositionV(pContext->inPositionV),
98 mbAllowInCell(pContext->mbAllowInCell),
99 mbIsVMLfound(pContext->mbIsVMLfound),
100 m_xContext(pContext->m_xContext),
101 m_bDiscardChildren(pContext->m_bDiscardChildren),
102 m_bTookChoice(pContext->m_bTookChoice)
103{
104 if (!mpParserState)
105 mpParserState = new OOXMLParserState();
106
107 mpParserState->incContextCount();
108}
109
110OOXMLFastContextHandler::~OOXMLFastContextHandler()
111{
112}
113
114bool OOXMLFastContextHandler::prepareMceContext(Token_t nElement, const uno::Reference<xml::sax::XFastAttributeList>& rAttribs)
115{
116 switch (oox::getBaseToken(nElement))
117 {
118 case XML_AlternateContent:
119 {
120 SavedAlternateState aState;
121 aState.m_bDiscardChildren = m_bDiscardChildren;
122 m_bDiscardChildren = false;
123 aState.m_bTookChoice = m_bTookChoice;
124 m_bTookChoice = false;
125 mpParserState->getSavedAlternateStates().push_back(aState);
126 }
127 break;
128 case XML_Choice:
129 {
130 OUString aRequires = rAttribs->getOptionalValue(XML_Requires);
131 static const char* aFeatures[] = {
132 "wps",
133 "wpg",
134 "w14",
135 };
136 for (const char *p : aFeatures)
137 {
138 if (aRequires.equalsAscii(p))
139 {
140 m_bTookChoice = true;
141 return false;
142 }
143 }
144 return true;
145 }
146 break;
147 case XML_Fallback:
148 // If Choice is already taken, then let's ignore the Fallback.
149 return m_bTookChoice;
150 break;
151 default:
152 SAL_WARN("writerfilter", "OOXMLFastContextHandler::prepareMceContext: unhandled element:" << oox::getBaseToken(nElement))do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "OOXMLFastContextHandler::prepareMceContext: unhandled element:"
<< oox::getBaseToken(nElement)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "152" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OOXMLFastContextHandler::prepareMceContext: unhandled element:"
<< oox::getBaseToken(nElement)), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "OOXMLFastContextHandler::prepareMceContext: unhandled element:"
<< oox::getBaseToken(nElement); ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "152" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "OOXMLFastContextHandler::prepareMceContext: unhandled element:"
<< oox::getBaseToken(nElement)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "152" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "OOXMLFastContextHandler::prepareMceContext: unhandled element:"
<< oox::getBaseToken(nElement)), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "OOXMLFastContextHandler::prepareMceContext: unhandled element:"
<< oox::getBaseToken(nElement); ::sal::detail::log( (::
SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "152" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
153 break;
154 }
155 return false;
156}
157
158// xml::sax::XFastContextHandler:
159void SAL_CALL OOXMLFastContextHandler::startFastElement
160(sal_Int32 Element,
161 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
162{
163 // Set xml:space value early, to allow child contexts use it when dealing with strings.
164 if (Attribs && Attribs->hasAttribute(oox::NMSP_xml | oox::XML_space))
165 {
166 mbPreserveSpace = Attribs->getValue(oox::NMSP_xml | oox::XML_space) == "preserve";
167 mbPreserveSpaceSet = true;
168 }
169 if (Element == (NMSP_officeMath | XML_oMathPara))
170 {
171 mnMathJcVal = eMathParaJc::CENTER;
172 mbIsMathPara = true;
173 }
174 if (Element == (NMSP_officeMath | XML_jc) && mpParent && mpParent->mpParent )
175 {
176 mbIsMathPara = true;
177 auto aAttrLst = Attribs->getFastAttributes();
178 if (aAttrLst[0].Value == "center") mpParent->mpParent->mnMathJcVal = eMathParaJc::CENTER;
179 if (aAttrLst[0].Value == "left") mpParent->mpParent->mnMathJcVal = eMathParaJc::LEFT;
180 if (aAttrLst[0].Value == "right") mpParent->mpParent->mnMathJcVal = eMathParaJc::RIGHT;
181 }
182
183 if (oox::getNamespace(Element) == NMSP_mce)
184 m_bDiscardChildren = prepareMceContext(Element, Attribs);
185
186 else if (!m_bDiscardChildren)
187 {
188 attributes(Attribs);
189 lcl_startFastElement(Element, Attribs);
190 }
191}
192
193void SAL_CALL OOXMLFastContextHandler::startUnknownElement
194(const OUString & /*Namespace*/, const OUString & /*Name*/,
195 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
196{
197}
198
199void SAL_CALL OOXMLFastContextHandler::endFastElement(sal_Int32 Element)
200{
201 if (Element == (NMSP_mce | XML_Choice) || Element == (NMSP_mce | XML_Fallback))
202 m_bDiscardChildren = false;
203 else if (Element == (NMSP_mce | XML_AlternateContent))
204 {
205 SavedAlternateState aState(mpParserState->getSavedAlternateStates().back());
206 mpParserState->getSavedAlternateStates().pop_back();
207 m_bDiscardChildren = aState.m_bDiscardChildren;
208 m_bTookChoice = aState.m_bTookChoice;
209 }
210 else if (!m_bDiscardChildren)
211 lcl_endFastElement(Element);
212}
213
214void OOXMLFastContextHandler::lcl_startFastElement
215(Token_t Element,
216 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
217{
218 OOXMLFactory::startAction(this);
219 if( Element == (NMSP_dmlWordDr|XML_positionV) )
220 inPositionV = true;
221 else if( Element == (NMSP_dmlWordDr|XML_positionH) )
222 inPositionV = false;
223
224}
225
226void OOXMLFastContextHandler::lcl_endFastElement
227(Token_t /*Element*/)
228{
229 OOXMLFactory::endAction(this);
230}
231
232void SAL_CALL OOXMLFastContextHandler::endUnknownElement
233(const OUString & , const OUString & )
234{
235}
236
237uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
238 OOXMLFastContextHandler::createFastChildContext
239(sal_Int32 Element,
240 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
241{
242 uno::Reference< xml::sax::XFastContextHandler > xResult;
243 if (oox::getNamespace(Element) != NMSP_mce && !m_bDiscardChildren)
244 xResult.set(lcl_createFastChildContext(Element, Attribs));
245 else if (oox::getNamespace(Element) == NMSP_mce)
246 xResult = this;
247
248 return xResult;
249}
250
251uno::Reference< xml::sax::XFastContextHandler >
252 OOXMLFastContextHandler::lcl_createFastChildContext
253(Token_t Element,
254 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
255{
256 return OOXMLFactory::createFastChildContext(this, Element);
257}
258
259uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
260OOXMLFastContextHandler::createUnknownChildContext
261(const OUString &,
262 const OUString &,
263 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
264{
265 return uno::Reference< xml::sax::XFastContextHandler >
266 (new OOXMLFastContextHandler(*const_cast<const OOXMLFastContextHandler *>(this)));
267}
268
269void SAL_CALL OOXMLFastContextHandler::characters
270(const OUString & aChars)
271{
272 lcl_characters(aChars);
273}
274
275void OOXMLFastContextHandler::lcl_characters
276(const OUString & rString)
277{
278 if (!m_bDiscardChildren)
279 OOXMLFactory::characters(this, rString);
280}
281
282void OOXMLFastContextHandler::setStream(Stream * pStream)
283{
284 mpStream = pStream;
285}
286
287OOXMLValue::Pointer_t OOXMLFastContextHandler::getValue() const
288{
289 return OOXMLValue::Pointer_t();
290}
291
292void OOXMLFastContextHandler::attributes
293(const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
294{
295 OOXMLFactory::attributes(this, Attribs);
296}
297
298void OOXMLFastContextHandler::startAction()
299{
300 OOXMLFactory::startAction(this);
301}
302
303void OOXMLFastContextHandler::endAction()
304{
305 OOXMLFactory::endAction(this);
306}
307
308void OOXMLFastContextHandler::setId(Id rId)
309{
310 mId = rId;
311}
312
313Id OOXMLFastContextHandler::getId() const
314{
315 return mId;
316}
317
318void OOXMLFastContextHandler::setDefine(Id nDefine)
319{
320 mnDefine = nDefine;
321}
322
323
324void OOXMLFastContextHandler::setToken(Token_t nToken)
325{
326 mnToken = nToken;
327}
328
329Token_t OOXMLFastContextHandler::getToken() const
330{
331 return mnToken;
332}
333
334void OOXMLFastContextHandler::sendTableDepth() const
335{
336 if (mnTableDepth <= 0)
337 return;
338
339 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
340 {
341 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
342 pProps->add(NS_ooxml::LN_tblDepth, pVal, OOXMLProperty::SPRM);
343 }
344 {
345 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
346 pProps->add(NS_ooxml::LN_inTbl, pVal, OOXMLProperty::SPRM);
347 }
348
349 mpStream->props(pProps.get());
350}
351
352void OOXMLFastContextHandler::setHandle()
353{
354 mpParserState->setHandle();
355 mpStream->info(mpParserState->getHandle());
356}
357
358void OOXMLFastContextHandler::startCharacterGroup()
359{
360 if (!isForwardEvents())
361 return;
362
363 if (mpParserState->isInCharacterGroup())
364 endCharacterGroup();
365
366 if (! mpParserState->isInParagraphGroup())
367 startParagraphGroup();
368
369 if (! mpParserState->isInCharacterGroup())
370 {
371 mpStream->startCharacterGroup();
372 mpParserState->setInCharacterGroup(true);
373 mpParserState->resolveCharacterProperties(*mpStream);
374 }
375
376 // tdf#108714 : if we have a postponed break information,
377 // then apply it now, before any other paragraph content.
378 mpParserState->resolvePostponedBreak(*mpStream);
379}
380
381void OOXMLFastContextHandler::endCharacterGroup()
382{
383 if (isForwardEvents() && mpParserState->isInCharacterGroup())
384 {
385 mpStream->endCharacterGroup();
386 mpParserState->setInCharacterGroup(false);
387 }
388}
389
390void OOXMLFastContextHandler::pushBiDiEmbedLevel() {}
391
392void OOXMLFastContextHandler::popBiDiEmbedLevel() {}
393
394void OOXMLFastContextHandler::startParagraphGroup()
395{
396 if (!isForwardEvents())
397 return;
398
399 if (mpParserState->isInParagraphGroup())
400 endParagraphGroup();
401
402 if (! mpParserState->isInSectionGroup())
403 startSectionGroup();
404
405 if (! mpParserState->isInParagraphGroup())
406 {
407 mpStream->startParagraphGroup();
408 mpParserState->setInParagraphGroup(true);
409 }
410}
411
412void OOXMLFastContextHandler::endParagraphGroup()
413{
414 if (isForwardEvents())
415 {
416 if (mpParserState->isInCharacterGroup())
417 endCharacterGroup();
418
419 if (mpParserState->isInParagraphGroup())
420 {
421 mpStream->endParagraphGroup();
422 mpParserState->setInParagraphGroup(false);
423 }
424 }
425}
426
427void OOXMLFastContextHandler::startSdt()
428{
429 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
430 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
431 pProps->add(NS_ooxml::LN_CT_SdtBlock_sdtContent, pVal, OOXMLProperty::ATTRIBUTE);
432 mpStream->props(pProps.get());
433}
434
435void OOXMLFastContextHandler::endSdt()
436{
437 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
438 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
439 pProps->add(NS_ooxml::LN_CT_SdtBlock_sdtEndContent, pVal, OOXMLProperty::ATTRIBUTE);
440 mpStream->props(pProps.get());
441}
442
443void OOXMLFastContextHandler::startSectionGroup()
444{
445 if (isForwardEvents())
446 {
447 if (mpParserState->isInSectionGroup())
448 endSectionGroup();
449
450 if (! mpParserState->isInSectionGroup())
451 {
452 mpStream->info(mpParserState->getHandle());
453 mpStream->startSectionGroup();
454 mpParserState->setInSectionGroup(true);
455 }
456 }
457}
458
459void OOXMLFastContextHandler::endSectionGroup()
460{
461 if (isForwardEvents())
462 {
463 if (mpParserState->isInParagraphGroup())
464 endParagraphGroup();
465
466 if (mpParserState->isInSectionGroup())
467 {
468 mpStream->endSectionGroup();
469 mpParserState->setInSectionGroup(false);
470 }
471 }
472}
473
474void OOXMLFastContextHandler::setLastParagraphInSection()
475{
476 mpParserState->setLastParagraphInSection(true);
477 mpStream->markLastParagraphInSection( );
478}
479
480void OOXMLFastContextHandler::setLastSectionGroup()
481{
482 mpStream->markLastSectionGroup( );
483}
484
485void OOXMLFastContextHandler::newProperty
486(Id /*nId*/, const OOXMLValue::Pointer_t& /*pVal*/)
487{
488}
489
490void OOXMLFastContextHandler::setPropertySet
491(const OOXMLPropertySet::Pointer_t& /* pPropertySet */)
492{
493}
494
495OOXMLPropertySet::Pointer_t OOXMLFastContextHandler::getPropertySet() const
496{
497 return OOXMLPropertySet::Pointer_t();
498}
499
500void OOXMLFastContextHandler::startField()
501{
502 startCharacterGroup();
503 if (isForwardEvents())
504 mpStream->text(&cFieldStart, 1);
505 endCharacterGroup();
506}
507
508void OOXMLFastContextHandler::fieldSeparator()
509{
510 startCharacterGroup();
511 if (isForwardEvents())
512 mpStream->text(&cFieldSep, 1);
513 endCharacterGroup();
514}
515
516void OOXMLFastContextHandler::endField()
517{
518 startCharacterGroup();
519 if (isForwardEvents())
520 mpStream->text(&cFieldEnd, 1);
521 endCharacterGroup();
522}
523
524void OOXMLFastContextHandler::lockField()
525{
526 startCharacterGroup();
527 if (isForwardEvents())
528 mpStream->text(&cFieldLock, 1);
529 endCharacterGroup();
530}
531
532void OOXMLFastContextHandler::ftnednref()
533{
534 if (isForwardEvents())
535 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uFtnEdnRef), 1);
536}
537
538void OOXMLFastContextHandler::ftnednsep()
539{
540 if (isForwardEvents())
541 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uFtnEdnSep), 1);
542}
543
544void OOXMLFastContextHandler::ftnedncont()
545{
546 if (isForwardEvents())
547 mpStream->text(&cFtnEdnCont, 1);
548}
549
550void OOXMLFastContextHandler::pgNum()
551{
552 if (isForwardEvents())
553 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uPgNum), 1);
554}
555
556void OOXMLFastContextHandler::tab()
557{
558 if (isForwardEvents())
559 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uTab), 1);
560}
561
562void OOXMLFastContextHandler::symbol()
563{
564 if (isForwardEvents())
565 sendPropertiesWithId(NS_ooxml::LN_EG_RunInnerContent_sym);
566}
567
568void OOXMLFastContextHandler::cr()
569{
570 if (isForwardEvents())
571 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uCR), 1);
572}
573
574void OOXMLFastContextHandler::noBreakHyphen()
575{
576 if (isForwardEvents())
577 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uNoBreakHyphen), 1);
578}
579
580void OOXMLFastContextHandler::softHyphen()
581{
582 if (isForwardEvents())
583 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uSoftHyphen), 1);
584}
585
586void OOXMLFastContextHandler::handleLastParagraphInSection()
587{
588 if (mpParserState->isLastParagraphInSection())
589 {
590 mpParserState->setLastParagraphInSection(false);
591 startSectionGroup();
592 }
593}
594
595void OOXMLFastContextHandler::endOfParagraph()
596{
597 if (! mpParserState->isInCharacterGroup())
598 startCharacterGroup();
599 if (isForwardEvents())
600 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uCR), 1);
601
602 mpParserState->getDocument()->incrementProgress();
603}
604
605void OOXMLFastContextHandler::startTxbxContent()
606{
607/*
608 This usually means there are recursive <w:p> elements, and the ones
609 inside and outside of w:txbxContent should not interfere (e.g.
610 the lastParagraphInSection setting). So save the whole state
611 and possibly start new groups for the nested content (not section
612 group though, as that'd cause the txbxContent to be moved onto
613 another page, I'm not sure how that should work exactly).
614*/
615 mpParserState->startTxbxContent();
616 startParagraphGroup();
617}
618
619void OOXMLFastContextHandler::endTxbxContent()
620{
621 endParagraphGroup();
622 mpParserState->endTxbxContent();
623}
624
625namespace {
626// XML schema defines white space as one of four characters:
627// #x9 (tab), #xA (line feed), #xD (carriage return), and #x20 (space)
628bool IsXMLWhitespace(sal_Unicode cChar)
629{
630 return cChar == 0x9 || cChar == 0xA || cChar == 0xD || cChar == 0x20;
631}
632
633OUString TrimXMLWhitespace(const OUString & sText)
634{
635 sal_Int32 nTrimmedStart = 0;
636 const sal_Int32 nLen = sText.getLength();
637 sal_Int32 nTrimmedEnd = nLen - 1;
638 while (nTrimmedStart < nLen && IsXMLWhitespace(sText[nTrimmedStart]))
639 ++nTrimmedStart;
640 while (nTrimmedStart <= nTrimmedEnd && IsXMLWhitespace(sText[nTrimmedEnd]))
641 --nTrimmedEnd;
642 if ((nTrimmedStart == 0) && (nTrimmedEnd == nLen - 1))
643 return sText;
644 else if (nTrimmedStart > nTrimmedEnd)
645 return OUString();
646 else
647 return sText.copy(nTrimmedStart, nTrimmedEnd-nTrimmedStart+1);
648}
649}
650
651void OOXMLFastContextHandler::text(const OUString & sText)
652{
653 if (!isForwardEvents())
654 return;
655
656 // tdf#108806: CRLFs in XML were converted to \n before this point.
657 // These must be converted to spaces before further processing.
658 OUString sNormalizedText = sText.replaceAll("\n", " ");
659 // tdf#108995: by default, leading and trailing white space is ignored;
660 // tabs are converted to spaces
661 if (!IsPreserveSpace())
662 {
663 sNormalizedText = TrimXMLWhitespace(sNormalizedText).replaceAll("\t", " ");
664 }
665 mpStream->utext(reinterpret_cast < const sal_uInt8 * >
666 (sNormalizedText.getStr()),
667 sNormalizedText.getLength());
668}
669
670void OOXMLFastContextHandler::positionOffset(const OUString& rText)
671{
672 if (isForwardEvents())
673 mpStream->positionOffset(rText, inPositionV);
674}
675
676void OOXMLFastContextHandler::ignore()
677{
678}
679
680void OOXMLFastContextHandler::alignH(const OUString& rText)
681{
682 if (isForwardEvents())
683 mpStream->align(rText, /*bVertical=*/false);
684}
685
686void OOXMLFastContextHandler::alignV(const OUString& rText)
687{
688 if (isForwardEvents())
689 mpStream->align(rText, /*bVertical=*/true);
690}
691
692void OOXMLFastContextHandler::positivePercentage(const OUString& rText)
693{
694 if (isForwardEvents())
695 mpStream->positivePercentage(rText);
696}
697
698void OOXMLFastContextHandler::startGlossaryEntry()
699{
700 if (isForwardEvents())
701 mpStream->startGlossaryEntry();
702}
703
704void OOXMLFastContextHandler::endGlossaryEntry()
705{
706 if (isForwardEvents())
707 mpStream->endGlossaryEntry();
708}
709
710void OOXMLFastContextHandler::propagateCharacterProperties()
711{
712 mpParserState->setCharacterProperties(getPropertySet());
713}
714
715void OOXMLFastContextHandler::propagateCellProperties()
716{
717 mpParserState->setCellProperties(getPropertySet());
718}
719
720void OOXMLFastContextHandler::propagateRowProperties()
721{
722 mpParserState->setRowProperties(getPropertySet());
723}
724
725void OOXMLFastContextHandler::propagateTableProperties()
726{
727 OOXMLPropertySet::Pointer_t pProps = getPropertySet();
728
729 mpParserState->setTableProperties(pProps);
730}
731
732void OOXMLFastContextHandler::sendCellProperties()
733{
734 mpParserState->resolveCellProperties(*mpStream);
735}
736
737void OOXMLFastContextHandler::sendRowProperties()
738{
739 mpParserState->resolveRowProperties(*mpStream);
740}
741
742void OOXMLFastContextHandler::sendTableProperties()
743{
744 mpParserState->resolveTableProperties(*mpStream);
745}
746
747void OOXMLFastContextHandler::clearTableProps()
748{
749 mpParserState->setTableProperties(new OOXMLPropertySet());
750}
751
752void OOXMLFastContextHandler::sendPropertiesWithId(Id nId)
753{
754 OOXMLValue::Pointer_t pValue(new OOXMLPropertySetValue(getPropertySet()));
755 OOXMLPropertySet::Pointer_t pPropertySet(new OOXMLPropertySet);
756
757 pPropertySet->add(nId, pValue, OOXMLProperty::SPRM);
758 mpStream->props(pPropertySet.get());
759}
760
761void OOXMLFastContextHandler::clearProps()
762{
763 setPropertySet(new OOXMLPropertySet());
764}
765
766void OOXMLFastContextHandler::setDefaultBooleanValue()
767{
768}
769
770void OOXMLFastContextHandler::setDefaultIntegerValue()
771{
772}
773
774void OOXMLFastContextHandler::setDefaultHexValue()
775{
776}
777
778void OOXMLFastContextHandler::setDefaultStringValue()
779{
780}
781
782void OOXMLFastContextHandler::setDocument(OOXMLDocumentImpl* pDocument)
783{
784 mpParserState->setDocument(pDocument);
785}
786
787OOXMLDocumentImpl* OOXMLFastContextHandler::getDocument()
788{
789 return mpParserState->getDocument();
790}
791
792void OOXMLFastContextHandler::setForwardEvents(bool bForwardEvents)
793{
794 mpParserState->setForwardEvents(bForwardEvents);
795}
796
797bool OOXMLFastContextHandler::isForwardEvents() const
798{
799 return mpParserState->isForwardEvents();
800}
801
802void OOXMLFastContextHandler::setXNoteId(const sal_Int32 nId)
803{
804 mpParserState->setXNoteId(nId);
805}
806
807void OOXMLFastContextHandler::setXNoteId(const OOXMLValue::Pointer_t& pValue)
808{
809 mpParserState->setXNoteId(sal_Int32(pValue->getInt()));
810}
811
812sal_Int32 OOXMLFastContextHandler::getXNoteId() const
813{
814 return mpParserState->getXNoteId();
815}
816
817void OOXMLFastContextHandler::resolveFootnote
818(const sal_Int32 nId)
819{
820 mpParserState->getDocument()->resolveFootnote
821 (*mpStream, 0, nId);
822}
823
824void OOXMLFastContextHandler::resolveEndnote(const sal_Int32 nId)
825{
826 mpParserState->getDocument()->resolveEndnote
827 (*mpStream, 0, nId);
828}
829
830void OOXMLFastContextHandler::resolveComment(const sal_Int32 nId)
831{
832 mpParserState->getDocument()->resolveComment(*mpStream, nId);
833}
834
835void OOXMLFastContextHandler::resolvePicture(const OUString & rId)
836{
837 mpParserState->getDocument()->resolvePicture(*mpStream, rId);
838}
839
840void OOXMLFastContextHandler::resolveHeader
841(const sal_Int32 type, const OUString & rId)
842{
843 mpParserState->getDocument()->resolveHeader(*mpStream, type, rId);
844}
845
846void OOXMLFastContextHandler::resolveFooter
847(const sal_Int32 type, const OUString & rId)
848{
849 mpParserState->getDocument()->resolveFooter(*mpStream, type, rId);
850}
851
852// Add the data pointed to by the reference as another property.
853void OOXMLFastContextHandler::resolveData(const OUString & rId)
854{
855 OOXMLDocument * objDocument = getDocument();
856 SAL_WARN_IF(!objDocument, "writerfilter", "no document to resolveData")do { if (true && (!objDocument)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "no document to resolveData"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"
), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no document to resolveData"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no document to resolveData"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "856" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "no document to resolveData") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "856" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "no document to resolveData"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"no document to resolveData"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
":" "856" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1
Assuming 'objDocument' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
857 if (!objDocument
3.1
'objDocument' is non-null
)
4
Taking false branch
858 return;
859
860 uno::Reference<io::XInputStream> xInputStream
861 (objDocument->getInputStreamForId(rId));
862
863 OOXMLValue::Pointer_t aValue(new OOXMLInputStreamValue(xInputStream));
5
Memory is allocated
864
865 newProperty(NS_ooxml::LN_inputstream, aValue);
866}
6
Potential leak of memory pointed to by 'aValue.pObj'
867
868OUString OOXMLFastContextHandler::getTargetForId
869(const OUString & rId)
870{
871 return mpParserState->getDocument()->getTargetForId(rId);
872}
873
874void OOXMLFastContextHandler::sendPropertyToParent()
875{
876 if (mpParent != nullptr)
877 {
878 OOXMLPropertySet::Pointer_t pProps(mpParent->getPropertySet());
879
880 if (pProps)
881 {
882 pProps->add(mId, getValue(), OOXMLProperty::SPRM);
883 }
884 }
885}
886
887void OOXMLFastContextHandler::sendPropertiesToParent()
888{
889 if (mpParent == nullptr)
890 return;
891
892 OOXMLPropertySet::Pointer_t pParentProps(mpParent->getPropertySet());
893
894 if (!pParentProps)
895 return;
896
897 OOXMLPropertySet::Pointer_t pProps(getPropertySet());
898
899 if (pProps)
900 {
901 OOXMLValue::Pointer_t pValue
902 (new OOXMLPropertySetValue(getPropertySet()));
903
904 pParentProps->add(getId(), pValue, OOXMLProperty::SPRM);
905
906 }
907}
908
909bool OOXMLFastContextHandler::IsPreserveSpace() const
910{
911 // xml:space attribute applies to all elements within the content of the element where it is specified,
912 // unless overridden with another instance of the xml:space attribute
913 if (mbPreserveSpaceSet)
914 return mbPreserveSpace;
915 if (mpParent)
916 return mpParent->IsPreserveSpace();
917 return false; // default value
918}
919
920/*
921 class OOXMLFastContextHandlerStream
922 */
923
924OOXMLFastContextHandlerStream::OOXMLFastContextHandlerStream
925(OOXMLFastContextHandler * pContext)
926: OOXMLFastContextHandler(pContext),
927 mpPropertySetAttrs(new OOXMLPropertySet)
928{
929}
930
931OOXMLFastContextHandlerStream::~OOXMLFastContextHandlerStream()
932{
933}
934
935void OOXMLFastContextHandlerStream::newProperty(Id nId,
936 const OOXMLValue::Pointer_t& pVal)
937{
938 if (nId != 0x0)
939 {
940 mpPropertySetAttrs->add(nId, pVal, OOXMLProperty::ATTRIBUTE);
941 }
942}
943
944void OOXMLFastContextHandlerStream::sendProperty(Id nId)
945{
946 OOXMLPropertySetEntryToString aHandler(nId);
947 getPropertySetAttrs()->resolve(aHandler);
948 const OUString & sText = aHandler.getString();
949 mpStream->utext(reinterpret_cast < const sal_uInt8 * >
950 (sText.getStr()),
951 sText.getLength());
952}
953
954
955OOXMLPropertySet::Pointer_t OOXMLFastContextHandlerStream::getPropertySet()
956 const
957{
958 return getPropertySetAttrs();
959}
960
961void OOXMLFastContextHandlerStream::handleHyperlink()
962{
963 OOXMLHyperlinkHandler aHyperlinkHandler(this);
964 getPropertySetAttrs()->resolve(aHyperlinkHandler);
965 aHyperlinkHandler.writetext();
966}
967
968/*
969 class OOXMLFastContextHandlerProperties
970 */
971OOXMLFastContextHandlerProperties::OOXMLFastContextHandlerProperties
972(OOXMLFastContextHandler * pContext)
973: OOXMLFastContextHandler(pContext), mpPropertySet(new OOXMLPropertySet),
974 mbResolve(false)
975{
976 if (pContext->getResource() == STREAM)
977 mbResolve = true;
978}
979
980OOXMLFastContextHandlerProperties::~OOXMLFastContextHandlerProperties()
981{
982}
983
984void OOXMLFastContextHandlerProperties::lcl_endFastElement
985(Token_t /*Element*/)
986{
987 try
988 {
989 endAction();
990
991 if (mbResolve)
992 {
993 if (isForwardEvents())
994 {
995 mpStream->props(mpPropertySet.get());
996 }
997 }
998 else
999 {
1000 sendPropertiesToParent();
1001 }
1002 }
1003 catch (const uno::RuntimeException&)
1004 {
1005 throw;
1006 }
1007 catch (const xml::sax::SAXException&)
1008 {
1009 throw;
1010 }
1011 catch (const uno::Exception& e)
1012 {
1013 auto a = cppu::getCaughtException();
1014 throw lang::WrappedTargetRuntimeException(e.Message, e.Context, a);
1015 }
1016}
1017
1018OOXMLValue::Pointer_t OOXMLFastContextHandlerProperties::getValue() const
1019{
1020 return OOXMLValue::Pointer_t(new OOXMLPropertySetValue(mpPropertySet));
1021}
1022
1023void OOXMLFastContextHandlerProperties::newProperty
1024(Id nId, const OOXMLValue::Pointer_t& pVal)
1025{
1026 if (nId != 0x0)
1027 {
1028 mpPropertySet->add(nId, pVal, OOXMLProperty::ATTRIBUTE);
1029 }
1030}
1031
1032void OOXMLFastContextHandlerProperties::handleXNotes()
1033{
1034 switch (mnToken)
1035 {
1036 case W_TOKEN(footnoteReference)(::oox::NMSP_doc | ::oox::XML_footnoteReference):
1037 {
1038 OOXMLFootnoteHandler aFootnoteHandler(this);
1039 mpPropertySet->resolve(aFootnoteHandler);
1040 }
1041 break;
1042 case W_TOKEN(endnoteReference)(::oox::NMSP_doc | ::oox::XML_endnoteReference):
1043 {
1044 OOXMLEndnoteHandler aEndnoteHandler(this);
1045 mpPropertySet->resolve(aEndnoteHandler);
1046 }
1047 break;
1048 default:
1049 break;
1050 }
1051}
1052
1053void OOXMLFastContextHandlerProperties::handleHdrFtr()
1054{
1055 switch (mnToken)
1056 {
1057 case W_TOKEN(footerReference)(::oox::NMSP_doc | ::oox::XML_footerReference):
1058 {
1059 OOXMLFooterHandler aFooterHandler(this);
1060 mpPropertySet->resolve(aFooterHandler);
1061 aFooterHandler.finalize();
1062 }
1063 break;
1064 case W_TOKEN(headerReference)(::oox::NMSP_doc | ::oox::XML_headerReference):
1065 {
1066 OOXMLHeaderHandler aHeaderHandler(this);
1067 mpPropertySet->resolve(aHeaderHandler);
1068 aHeaderHandler.finalize();
1069 }
1070 break;
1071 default:
1072 break;
1073 }
1074}
1075
1076void OOXMLFastContextHandlerProperties::handleComment()
1077{
1078 OOXMLCommentHandler aCommentHandler(this);
1079 getPropertySet()->resolve(aCommentHandler);
1080}
1081
1082void OOXMLFastContextHandlerProperties::handlePicture()
1083{
1084 OOXMLPictureHandler aPictureHandler(this);
1085 getPropertySet()->resolve(aPictureHandler);
1086}
1087
1088void OOXMLFastContextHandlerProperties::handleBreak()
1089{
1090 if(isForwardEvents())
1091 {
1092 OOXMLBreakHandler aBreakHandler(*mpStream);
1093 getPropertySet()->resolve(aBreakHandler);
1094 }
1095}
1096
1097// tdf#108714 : allow <w:br> at block level (despite this is illegal according to ECMA-376-1:2016)
1098void OOXMLFastContextHandlerProperties::handleOutOfOrderBreak()
1099{
1100 if(isForwardEvents())
1101 {
1102 mpParserState->setPostponedBreak(getPropertySet());
1103 }
1104}
1105
1106void OOXMLFastContextHandlerProperties::handleOLE()
1107{
1108 OOXMLOLEHandler aOLEHandler(this);
1109 getPropertySet()->resolve(aOLEHandler);
1110}
1111
1112void OOXMLFastContextHandlerProperties::handleFontRel()
1113{
1114 OOXMLEmbeddedFontHandler handler(this);
1115 getPropertySet()->resolve(handler);
1116}
1117
1118void OOXMLFastContextHandlerProperties::handleHyperlinkURL() {
1119 OOXMLHyperlinkURLHandler aHyperlinkURLHandler(this);
1120 getPropertySet()->resolve(aHyperlinkURLHandler);
1121}
1122
1123void OOXMLFastContextHandlerProperties::setPropertySet
1124(const OOXMLPropertySet::Pointer_t& pPropertySet)
1125{
1126 if (pPropertySet)
1127 mpPropertySet = pPropertySet;
1128}
1129
1130OOXMLPropertySet::Pointer_t
1131OOXMLFastContextHandlerProperties::getPropertySet() const
1132{
1133 return mpPropertySet;
1134}
1135
1136/*
1137 * class OOXMLFasContextHandlerPropertyTable
1138 */
1139
1140OOXMLFastContextHandlerPropertyTable::OOXMLFastContextHandlerPropertyTable
1141(OOXMLFastContextHandler * pContext)
1142: OOXMLFastContextHandlerProperties(pContext)
1143{
1144}
1145
1146OOXMLFastContextHandlerPropertyTable::~OOXMLFastContextHandlerPropertyTable()
1147{
1148}
1149
1150void OOXMLFastContextHandlerPropertyTable::lcl_endFastElement
1151(Token_t /*Element*/)
1152{
1153 OOXMLPropertySet::Pointer_t pPropSet(mpPropertySet->clone());
1154 OOXMLTable::ValuePointer_t pTmpVal
1155 (new OOXMLPropertySetValue(pPropSet));
1156
1157 mTable.add(pTmpVal);
1158
1159 writerfilter::Reference<Table>::Pointer_t pTable(mTable.clone());
1160
1161 mpStream->table(mId, pTable);
1162
1163 endAction();
1164}
1165
1166/*
1167 class OOXMLFastContextHandlerValue
1168*/
1169
1170OOXMLFastContextHandlerValue::OOXMLFastContextHandlerValue
1171(OOXMLFastContextHandler * pContext)
1172: OOXMLFastContextHandler(pContext)
1173{
1174}
1175
1176OOXMLFastContextHandlerValue::~OOXMLFastContextHandlerValue()
1177{
1178}
1179
1180void OOXMLFastContextHandlerValue::setValue(const OOXMLValue::Pointer_t& pValue)
1181{
1182 mpValue = pValue;
1183}
1184
1185OOXMLValue::Pointer_t OOXMLFastContextHandlerValue::getValue() const
1186{
1187 return mpValue;
1188}
1189
1190void OOXMLFastContextHandlerValue::lcl_endFastElement
1191(Token_t /*Element*/)
1192{
1193 sendPropertyToParent();
1194
1195 endAction();
1196}
1197
1198void OOXMLFastContextHandlerValue::setDefaultBooleanValue()
1199{
1200 if (!mpValue)
1201 {
1202 OOXMLValue::Pointer_t pValue = OOXMLBooleanValue::Create(true);
1203 setValue(pValue);
1204 }
1205}
1206
1207void OOXMLFastContextHandlerValue::setDefaultIntegerValue()
1208{
1209 if (!mpValue)
1210 {
1211 OOXMLValue::Pointer_t pValue = OOXMLIntegerValue::Create(0);
1212 setValue(pValue);
1213 }
1214}
1215
1216void OOXMLFastContextHandlerValue::setDefaultHexValue()
1217{
1218 if (!mpValue)
1219 {
1220 OOXMLValue::Pointer_t pValue(new OOXMLHexValue(sal_uInt32(0)));
1221 setValue(pValue);
1222 }
1223}
1224
1225void OOXMLFastContextHandlerValue::setDefaultStringValue()
1226{
1227 if (!mpValue)
1228 {
1229 OOXMLValue::Pointer_t pValue(new OOXMLStringValue(OUString()));
1230 setValue(pValue);
1231 }
1232}
1233
1234// ECMA-376-1:2016 17.3.2.8; https://www.unicode.org/reports/tr9/#Explicit_Directional_Embeddings
1235void OOXMLFastContextHandlerValue::pushBiDiEmbedLevel()
1236{
1237 const bool bRtl
1238 = mpValue && mpValue->getInt() == NS_ooxml::LN_Value_ST_Direction_rtl;
1239 OOXMLFactory::characters(this, bRtl ? OUString(u"\u202B") : OUString(u"\u202A")); // RLE / LRE
1240}
1241
1242void OOXMLFastContextHandlerValue::popBiDiEmbedLevel()
1243{
1244 OOXMLFactory::characters(this, u"\u202C"); // PDF (POP DIRECTIONAL FORMATTING)
1245}
1246
1247void OOXMLFastContextHandlerValue::handleGridAfter()
1248{
1249 if (!getValue())
1250 return;
1251
1252 if (OOXMLFastContextHandler* pTableRowProperties = getParent())
1253 {
1254 if (OOXMLFastContextHandler* pTableRow = pTableRowProperties->getParent())
1255 // Save the value into the table row context, so it can be handled
1256 // right before the end of the row.
1257 pTableRow->setGridAfter(getValue());
1258 }
1259}
1260
1261/*
1262 class OOXMLFastContextHandlerTable
1263*/
1264
1265OOXMLFastContextHandlerTable::OOXMLFastContextHandlerTable
1266(OOXMLFastContextHandler * pContext)
1267: OOXMLFastContextHandler(pContext)
1268{
1269}
1270
1271OOXMLFastContextHandlerTable::~OOXMLFastContextHandlerTable()
1272{
1273}
1274
1275uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
1276OOXMLFastContextHandlerTable::createFastChildContext
1277(sal_Int32 Element,
1278 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1279{
1280 addCurrentChild();
1281
1282 mCurrentChild.set(OOXMLFastContextHandler::createFastChildContext(Element, Attribs));
1283
1284 return mCurrentChild;
1285}
1286
1287void OOXMLFastContextHandlerTable::lcl_endFastElement
1288(Token_t /*Element*/)
1289{
1290 addCurrentChild();
1291
1292 writerfilter::Reference<Table>::Pointer_t pTable(mTable.clone());
1293 if (isForwardEvents() && mId != 0x0)
1294 {
1295 mpStream->table(mId, pTable);
1296 }
1297}
1298
1299void OOXMLFastContextHandlerTable::addCurrentChild()
1300{
1301 OOXMLFastContextHandler * pHandler = dynamic_cast<OOXMLFastContextHandler*>(mCurrentChild.get());
1302 if (pHandler != nullptr)
1303 {
1304 OOXMLValue::Pointer_t pValue(pHandler->getValue());
1305
1306 if (pValue)
1307 {
1308 OOXMLTable::ValuePointer_t pTmpVal(pValue->clone());
1309 mTable.add(pTmpVal);
1310 }
1311 }
1312}
1313
1314/*
1315 class OOXMLFastContextHandlerXNote
1316 */
1317
1318OOXMLFastContextHandlerXNote::OOXMLFastContextHandlerXNote
1319 (OOXMLFastContextHandler * pContext)
1320 : OOXMLFastContextHandlerProperties(pContext)
1321 , mbForwardEventsSaved(false)
1322 , mnMyXNoteId(0)
1323 , mnMyXNoteType(0)
1324{
1325}
1326
1327OOXMLFastContextHandlerXNote::~OOXMLFastContextHandlerXNote()
1328{
1329}
1330
1331void OOXMLFastContextHandlerXNote::lcl_startFastElement
1332(Token_t /*Element*/,
1333 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
1334{
1335 mbForwardEventsSaved = isForwardEvents();
1336
1337 // If this is the note we're looking for or this is the footnote separator one.
1338 if (mnMyXNoteId == getXNoteId() || static_cast<sal_uInt32>(mnMyXNoteType) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
1339 setForwardEvents(true);
1340 else
1341 setForwardEvents(false);
1342
1343 startAction();
1344}
1345
1346void OOXMLFastContextHandlerXNote::lcl_endFastElement
1347(Token_t Element)
1348{
1349 endAction();
1350
1351 OOXMLFastContextHandlerProperties::lcl_endFastElement(Element);
1352
1353 setForwardEvents(mbForwardEventsSaved);
1354}
1355
1356void OOXMLFastContextHandlerXNote::checkId(const OOXMLValue::Pointer_t& pValue)
1357{
1358 mnMyXNoteId = sal_Int32(pValue->getInt());
1359}
1360
1361void OOXMLFastContextHandlerXNote::checkType(const OOXMLValue::Pointer_t& pValue)
1362{
1363 mnMyXNoteType = pValue->getInt();
1364}
1365
1366/*
1367 class OOXMLFastContextHandlerTextTableCell
1368 */
1369
1370OOXMLFastContextHandlerTextTableCell::OOXMLFastContextHandlerTextTableCell
1371(OOXMLFastContextHandler * pContext)
1372: OOXMLFastContextHandler(pContext)
1373{
1374}
1375
1376OOXMLFastContextHandlerTextTableCell::~OOXMLFastContextHandlerTextTableCell()
1377{
1378}
1379
1380void OOXMLFastContextHandlerTextTableCell::startCell()
1381{
1382 if (isForwardEvents())
1383 {
1384 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
1385 {
1386 OOXMLValue::Pointer_t pVal = OOXMLBooleanValue::Create(mnTableDepth > 0);
1387 pProps->add(NS_ooxml::LN_tcStart, pVal, OOXMLProperty::SPRM);
1388 }
1389
1390 mpStream->props(pProps.get());
1391 }
1392}
1393
1394void OOXMLFastContextHandlerTextTableCell::endCell()
1395{
1396 if (!isForwardEvents())
1397 return;
1398
1399 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
1400 {
1401 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
1402 pProps->add(NS_ooxml::LN_tblDepth, pVal, OOXMLProperty::SPRM);
1403 }
1404 {
1405 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
1406 pProps->add(NS_ooxml::LN_inTbl, pVal, OOXMLProperty::SPRM);
1407 }
1408 {
1409 OOXMLValue::Pointer_t pVal = OOXMLBooleanValue::Create(mnTableDepth > 0);
1410 pProps->add(NS_ooxml::LN_tblCell, pVal, OOXMLProperty::SPRM);
1411 }
1412 {
1413 OOXMLValue::Pointer_t pVal = OOXMLBooleanValue::Create(mnTableDepth > 0);
1414 pProps->add(NS_ooxml::LN_tcEnd, pVal, OOXMLProperty::SPRM);
1415 }
1416
1417 mpStream->props(pProps.get());
1418}
1419
1420/*
1421 class OOXMLFastContextHandlerTextTableRow
1422 */
1423
1424OOXMLFastContextHandlerTextTableRow::OOXMLFastContextHandlerTextTableRow
1425(OOXMLFastContextHandler * pContext)
1426: OOXMLFastContextHandler(pContext)
1427{
1428}
1429
1430OOXMLFastContextHandlerTextTableRow::~OOXMLFastContextHandlerTextTableRow()
1431{
1432}
1433
1434void OOXMLFastContextHandlerTextTableRow::startRow()
1435{
1436}
1437
1438void OOXMLFastContextHandlerTextTableRow::endRow()
1439{
1440 if (mpGridAfter)
1441 {
1442 // Grid after is the same as grid before, the empty cells are just
1443 // inserted after the real ones, not before.
1444 handleGridBefore(mpGridAfter);
1445 mpGridAfter = nullptr;
1446 }
1447
1448 startParagraphGroup();
1449
1450 if (isForwardEvents())
1451 {
1452 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
1453 {
1454 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
1455 pProps->add(NS_ooxml::LN_tblDepth, pVal, OOXMLProperty::SPRM);
1456 }
1457 {
1458 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
1459 pProps->add(NS_ooxml::LN_inTbl, pVal, OOXMLProperty::SPRM);
1460 }
1461 {
1462 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
1463 pProps->add(NS_ooxml::LN_tblRow, pVal, OOXMLProperty::SPRM);
1464 }
1465
1466 mpStream->props(pProps.get());
1467 }
1468
1469 startCharacterGroup();
1470
1471 if (isForwardEvents())
1472 mpStream->utext(reinterpret_cast<const sal_uInt8*>(&uCR), 1);
1473
1474 endCharacterGroup();
1475 endParagraphGroup();
1476}
1477
1478namespace {
1479OOXMLValue::Pointer_t fakeNoBorder()
1480{
1481 OOXMLPropertySet::Pointer_t pProps( new OOXMLPropertySet );
1482 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(0);
1483 pProps->add(NS_ooxml::LN_CT_Border_val, pVal, OOXMLProperty::ATTRIBUTE);
1484 OOXMLValue::Pointer_t pValue( new OOXMLPropertySetValue( pProps ));
1485 return pValue;
1486}
1487}
1488
1489// Handle w:gridBefore here by faking necessary input that'll fake cells. I'm apparently
1490// not insane enough to find out how to add cells in dmapper.
1491void OOXMLFastContextHandlerTextTableRow::handleGridBefore( const OOXMLValue::Pointer_t& val )
1492{
1493 // start removing: disable for w:gridBefore
1494 if (!mpGridAfter)
1495 return;
1496
1497 int count = val->getInt();
1498 for( int i = 0;
1499 i < count;
1500 ++i )
1501 {
1502 endOfParagraph();
1503
1504 if (isForwardEvents())
1505 {
1506 // This whole part is OOXMLFastContextHandlerTextTableCell::endCell() .
1507 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
1508 {
1509 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
1510 pProps->add(NS_ooxml::LN_tblDepth, pVal, OOXMLProperty::SPRM);
1511 }
1512 {
1513 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
1514 pProps->add(NS_ooxml::LN_inTbl, pVal, OOXMLProperty::SPRM);
1515 }
1516 {
1517 OOXMLValue::Pointer_t pVal = OOXMLBooleanValue::Create(mnTableDepth > 0);
1518 pProps->add(NS_ooxml::LN_tblCell, pVal, OOXMLProperty::SPRM);
1519 }
1520
1521 mpStream->props(pProps.get());
1522
1523 // fake <w:tcBorders> with no border
1524 OOXMLPropertySet::Pointer_t pCellProps( new OOXMLPropertySet );
1525 {
1526 OOXMLPropertySet::Pointer_t pBorderProps( new OOXMLPropertySet );
1527 static Id borders[] = { NS_ooxml::LN_CT_TcBorders_top, NS_ooxml::LN_CT_TcBorders_bottom,
1528 NS_ooxml::LN_CT_TcBorders_start, NS_ooxml::LN_CT_TcBorders_end };
1529 for(sal_uInt32 border : borders)
1530 pBorderProps->add(border, fakeNoBorder(), OOXMLProperty::SPRM);
1531 OOXMLValue::Pointer_t pValue( new OOXMLPropertySetValue( pBorderProps ));
1532 pCellProps->add(NS_ooxml::LN_CT_TcPrBase_tcBorders, pValue, OOXMLProperty::SPRM);
1533 mpParserState->setCellProperties(pCellProps);
1534 }
1535 }
1536
1537 sendCellProperties();
1538 endParagraphGroup();
1539 }
1540}
1541
1542/*
1543 class OOXMLFastContextHandlerTextTable
1544 */
1545
1546OOXMLFastContextHandlerTextTable::OOXMLFastContextHandlerTextTable
1547(OOXMLFastContextHandler * pContext)
1548: OOXMLFastContextHandler(pContext)
1549{
1550}
1551
1552OOXMLFastContextHandlerTextTable::~OOXMLFastContextHandlerTextTable()
1553{
1554 clearTableProps();
1555}
1556
1557void OOXMLFastContextHandlerTextTable::lcl_startFastElement
1558(Token_t /*Element*/,
1559 const uno::Reference< xml::sax::XFastAttributeList > & /*Attribs*/)
1560{
1561 mpParserState->startTable();
1562 mnTableDepth++;
1563
1564 OOXMLPropertySet::Pointer_t pProps( new OOXMLPropertySet );
1565 {
1566 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
1567 pProps->add(NS_ooxml::LN_tblStart, pVal, OOXMLProperty::SPRM);
1568 }
1569 mpParserState->setCharacterProperties(pProps);
1570
1571 startAction();
1572}
1573
1574void OOXMLFastContextHandlerTextTable::lcl_endFastElement
1575(Token_t /*Element*/)
1576{
1577 endAction();
1578
1579 OOXMLPropertySet::Pointer_t pProps( new OOXMLPropertySet );
1580 {
1581 OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
1582 pProps->add(NS_ooxml::LN_tblEnd, pVal, OOXMLProperty::SPRM);
1583 }
1584 mpParserState->setCharacterProperties(pProps);
1585
1586 mnTableDepth--;
1587 mpParserState->endTable();
1588}
1589
1590// tdf#111550
1591void OOXMLFastContextHandlerTextTable::start_P_Tbl()
1592{
1593 // Normally, when one paragraph ends, and another begins,
1594 // in OOXMLFactory_wml::endAction handler for <w:p>,
1595 // pHandler->endOfParagraph() is called, which (among other things)
1596 // calls TableManager::setHandle() to update current cell's starting point.
1597 // Then, in OOXMLFactory_wml::startAction for next <w:p>,
1598 // pHandler->startParagraphGroup() is called, which ends previous group,
1599 // and there, it pushes cells to row in TableManager::endParagraphGroup()
1600 // (cells have correct bounds defined by mCurHandle).
1601 // When a table is child of a <w:p>, that paragraph doesn't end before nested
1602 // paragraph begins. So, pHandler->endOfParagraph() was not (and should not be)
1603 // called. But as next paragraph starts, is the previous group is closed, then
1604 // cells will have wrong boundings. Here, we know that we *are* in paragraph
1605 // group, but it should not be finished.
1606 mpParserState->setInParagraphGroup(false);
1607}
1608
1609/*
1610 class OOXMLFastContextHandlerShape
1611 */
1612
1613OOXMLFastContextHandlerShape::OOXMLFastContextHandlerShape
1614(OOXMLFastContextHandler * pContext)
1615: OOXMLFastContextHandlerProperties(pContext), m_bShapeSent( false ),
1616 m_bShapeStarted(false), m_bShapeContextPushed(false)
1617{
1618}
1619
1620OOXMLFastContextHandlerShape::~OOXMLFastContextHandlerShape()
1621{
1622 if (m_bShapeContextPushed)
1623 getDocument()->popShapeContext();
1624}
1625
1626void OOXMLFastContextHandlerShape::lcl_startFastElement
1627(Token_t Element,
1628 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1629{
1630 startAction();
1631
1632 if (mrShapeContext.is())
1633 {
1634 mrShapeContext->startFastElement(Element, Attribs);
1635 }
1636}
1637
1638void SAL_CALL OOXMLFastContextHandlerShape::startUnknownElement
1639(const OUString & Namespace,
1640 const OUString & Name,
1641 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1642{
1643 if (mrShapeContext.is())
1644 mrShapeContext->startUnknownElement(Namespace, Name, Attribs);
1645}
1646
1647void OOXMLFastContextHandlerShape::setToken(Token_t nToken)
1648{
1649 if (nToken == Token_t(NMSP_wps | XML_wsp) || nToken == Token_t(NMSP_dmlPicture | XML_pic))
1650 {
1651 // drawingML shapes are independent, <wps:bodyPr> is not parsed after
1652 // shape contents without pushing/popping the stack.
1653 m_bShapeContextPushed = true;
1654 getDocument()->pushShapeContext();
1655 }
1656
1657 mrShapeContext.set(getDocument()->getShapeContext());
1658 if (!mrShapeContext.is())
1659 {
1660 // Define the shape context for the whole document
1661 mrShapeContext = css::xml::sax::FastShapeContextHandler::create(getComponentContext());
1662 getDocument()->setShapeContext(mrShapeContext);
1663 }
1664
1665 mrShapeContext->setModel(getDocument()->getModel());
1666 uno::Reference<document::XDocumentPropertiesSupplier> xDocSupplier(getDocument()->getModel(), uno::UNO_QUERY_THROW);
1667 mrShapeContext->setDocumentProperties(xDocSupplier->getDocumentProperties());
1668 mrShapeContext->setDrawPage(getDocument()->getDrawPage());
1669 mrShapeContext->setMediaDescriptor(getDocument()->getMediaDescriptor());
1670
1671 mrShapeContext->setRelationFragmentPath(mpParserState->getTarget());
1672
1673 auto xGraphicMapper = getDocument()->getGraphicMapper();
1674
1675 if (xGraphicMapper.is())
1676 mrShapeContext->setGraphicMapper(xGraphicMapper);
1677
1678 OOXMLFastContextHandler::setToken(nToken);
1679
1680 if (mrShapeContext.is())
1681 mrShapeContext->setStartToken(nToken);
1682}
1683
1684void OOXMLFastContextHandlerShape::sendShape( Token_t Element )
1685{
1686 if ( !mrShapeContext.is() || m_bShapeSent )
1687 return;
1688
1689 awt::Point aPosition = mpStream->getPositionOffset();
1690 mrShapeContext->setPosition(aPosition);
1691 uno::Reference<drawing::XShape> xShape(mrShapeContext->getShape());
1692 m_bShapeSent = true;
1693 if (!xShape.is())
1694 return;
1695
1696 OOXMLValue::Pointer_t
1697 pValue(new OOXMLShapeValue(xShape));
1698 newProperty(NS_ooxml::LN_shape, pValue);
1699
1700 bool bIsPicture = Element == ( NMSP_dmlPicture | XML_pic );
1701
1702 //tdf#87569: Fix table layout with correcting anchoring
1703 //If anchored object is in table, Word calculates its position from cell border
1704 //instead of page (what is set in the sample document)
1705 uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY);
1706 if (mnTableDepth > 0 && xShapePropSet.is() && mbIsVMLfound) //if we had a table
1707 {
1708 xShapePropSet->setPropertyValue(dmapper::getPropertyName(dmapper::PROP_FOLLOW_TEXT_FLOW),
1709 uno::makeAny(mbAllowInCell));
1710 }
1711 // Notify the dmapper that the shape is ready to use
1712 if ( !bIsPicture )
1713 {
1714 mpStream->startShape( xShape );
1715 m_bShapeStarted = true;
1716 }
1717}
1718
1719void OOXMLFastContextHandlerShape::lcl_endFastElement
1720(Token_t Element)
1721{
1722 if (!isForwardEvents())
1723 return;
1724
1725 if (mrShapeContext.is())
1726 {
1727 mrShapeContext->endFastElement(Element);
1728 sendShape( Element );
1729 }
1730
1731 OOXMLFastContextHandlerProperties::lcl_endFastElement(Element);
1732
1733 // Ending the shape should be the last thing to do
1734 bool bIsPicture = Element == ( NMSP_dmlPicture | XML_pic );
1735 if ( !bIsPicture && m_bShapeStarted)
1736 mpStream->endShape( );
1737}
1738
1739void SAL_CALL OOXMLFastContextHandlerShape::endUnknownElement
1740(const OUString & Namespace,
1741 const OUString & Name)
1742{
1743 if (mrShapeContext.is())
1744 mrShapeContext->endUnknownElement(Namespace, Name);
1745}
1746
1747uno::Reference< xml::sax::XFastContextHandler >
1748OOXMLFastContextHandlerShape::lcl_createFastChildContext
1749(Token_t Element,
1750 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1751{
1752 uno::Reference< xml::sax::XFastContextHandler > xContextHandler;
1753
1754 bool bGroupShape = Element == Token_t(NMSP_vml | XML_group);
1755 // drawingML version also counts as a group shape.
1756 bGroupShape |= mrShapeContext->getStartToken() == Token_t(NMSP_wpg | XML_wgp);
1757 mbIsVMLfound = (getNamespace(Element) == NMSP_vmlOffice) || (getNamespace(Element) == NMSP_vml);
1758 switch (oox::getNamespace(Element))
1759 {
1760 case NMSP_doc:
1761 case NMSP_vmlWord:
1762 case NMSP_vmlOffice:
1763 if (!bGroupShape)
1764 xContextHandler.set(OOXMLFactory::createFastChildContextFromStart(this, Element));
1765 [[fallthrough]];
1766 default:
1767 if (!xContextHandler.is())
1768 {
1769 if (mrShapeContext.is())
1770 {
1771 uno::Reference<XFastContextHandler> pChildContext =
1772 mrShapeContext->createFastChildContext(Element, Attribs);
1773
1774 OOXMLFastContextHandlerWrapper * pWrapper =
1775 new OOXMLFastContextHandlerWrapper(this,
1776 pChildContext,
1777 this);
1778
1779 //tdf129888 store allowincell attribute of the VML shape
1780 if (Attribs->hasAttribute(NMSP_vmlOffice | XML_allowincell))
1781 mbAllowInCell
1782 = !(Attribs->getValue(NMSP_vmlOffice | XML_allowincell) == "f");
1783
1784 if (!bGroupShape)
1785 {
1786 pWrapper->addNamespace(NMSP_doc);
1787 pWrapper->addNamespace(NMSP_vmlWord);
1788 pWrapper->addNamespace(NMSP_vmlOffice);
1789 pWrapper->addToken( NMSP_vml|XML_textbox );
1790 }
1791 xContextHandler.set(pWrapper);
1792 }
1793 else
1794 xContextHandler.set(this);
1795 }
1796 break;
1797 }
1798
1799 // VML import of shape text is already handled by
1800 // OOXMLFastContextHandlerWrapper::lcl_createFastChildContext(), here we
1801 // handle the WPS import of shape text, as there the parent context is a
1802 // Shape one, so a different situation.
1803 if (Element == static_cast<sal_Int32>(NMSP_wps | XML_txbx) ||
1804 Element == static_cast<sal_Int32>(NMSP_wps | XML_linkedTxbx) )
1805 sendShape(Element);
1806
1807 return xContextHandler;
1808}
1809
1810uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
1811OOXMLFastContextHandlerShape::createUnknownChildContext
1812(const OUString & Namespace,
1813 const OUString & Name,
1814 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1815{
1816 uno::Reference< xml::sax::XFastContextHandler > xResult;
1817
1818 if (mrShapeContext.is())
1819 xResult.set(mrShapeContext->createUnknownChildContext
1820 (Namespace, Name, Attribs));
1821
1822 return xResult;
1823}
1824
1825void OOXMLFastContextHandlerShape::lcl_characters
1826(const OUString & aChars)
1827{
1828 if (mrShapeContext.is())
1829 mrShapeContext->characters(aChars);
1830}
1831
1832/*
1833 class OOXMLFastContextHandlerWrapper
1834*/
1835
1836OOXMLFastContextHandlerWrapper::OOXMLFastContextHandlerWrapper
1837(OOXMLFastContextHandler * pParent,
1838 uno::Reference<XFastContextHandler> const & xContext,
1839 rtl::Reference<OOXMLFastContextHandlerShape> const & xShapeHandler)
1840 : OOXMLFastContextHandler(pParent),
1841 mxWrappedContext(xContext),
1842 mxShapeHandler(xShapeHandler)
1843{
1844 setId(pParent->getId());
1845 setToken(pParent->getToken());
1846 setPropertySet(pParent->getPropertySet());
1847}
1848
1849OOXMLFastContextHandlerWrapper::~OOXMLFastContextHandlerWrapper()
1850{
1851}
1852
1853void SAL_CALL OOXMLFastContextHandlerWrapper::startUnknownElement
1854(const OUString & Namespace,
1855 const OUString & Name,
1856 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1857{
1858 if (mxWrappedContext.is())
1859 mxWrappedContext->startUnknownElement(Namespace, Name, Attribs);
1860}
1861
1862void SAL_CALL OOXMLFastContextHandlerWrapper::endUnknownElement
1863(const OUString & Namespace,
1864 const OUString & Name)
1865{
1866 if (mxWrappedContext.is())
1867 mxWrappedContext->endUnknownElement(Namespace, Name);
1868}
1869
1870uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
1871OOXMLFastContextHandlerWrapper::createUnknownChildContext
1872(const OUString & Namespace,
1873 const OUString & Name,
1874 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1875{
1876 uno::Reference< xml::sax::XFastContextHandler > xResult;
1877
1878 if (mxWrappedContext.is())
1879 xResult = mxWrappedContext->createUnknownChildContext
1880 (Namespace, Name, Attribs);
1881 else
1882 xResult.set(this);
1883
1884 return xResult;
1885}
1886
1887void OOXMLFastContextHandlerWrapper::attributes
1888(const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1889{
1890 if (mxWrappedContext.is())
1891 {
1892 OOXMLFastContextHandler * pHandler = getFastContextHandler();
1893 if (pHandler != nullptr)
1894 pHandler->attributes(Attribs);
1895 }
1896}
1897
1898OOXMLFastContextHandler::ResourceEnum_t
1899OOXMLFastContextHandlerWrapper::getResource() const
1900{
1901 return UNKNOWN;
1902}
1903
1904void OOXMLFastContextHandlerWrapper::addNamespace(Id nId)
1905{
1906 mMyNamespaces.insert(nId);
1907}
1908
1909void OOXMLFastContextHandlerWrapper::addToken( Token_t Token )
1910{
1911 mMyTokens.insert( Token );
1912}
1913
1914void OOXMLFastContextHandlerWrapper::lcl_startFastElement
1915(Token_t Element,
1916 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1917{
1918 if (mxWrappedContext.is())
1919 mxWrappedContext->startFastElement(Element, Attribs);
1920}
1921
1922void OOXMLFastContextHandlerWrapper::lcl_endFastElement
1923(Token_t Element)
1924{
1925 if (mxWrappedContext.is())
1926 mxWrappedContext->endFastElement(Element);
1927}
1928
1929uno::Reference< xml::sax::XFastContextHandler >
1930OOXMLFastContextHandlerWrapper::lcl_createFastChildContext
1931(Token_t Element,
1932 const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
1933{
1934 uno::Reference< xml::sax::XFastContextHandler > xResult;
1935
1936 bool bInNamespaces = mMyNamespaces.find(oox::getNamespace(Element)) != mMyNamespaces.end();
1937 bool bInTokens = mMyTokens.find( Element ) != mMyTokens.end( );
1938
1939 // We have methods to _add_ individual tokens or whole namespaces to be
1940 // processed by writerfilter (instead of oox), but we have no method to
1941 // filter out a single token. Just hardwire the 'wrap' and 'signatureline' tokens
1942 // here until we need a more generic solution.
1943 bool bIsWrap = Element == static_cast<sal_Int32>(NMSP_vmlWord | XML_wrap);
1944 bool bIsSignatureLine = Element == static_cast<sal_Int32>(NMSP_vmlOffice | XML_signatureline);
1945 bool bSkipImages = getDocument()->IsSkipImages() && oox::getNamespace(Element) == NMSP_dml &&
1946 (oox::getBaseToken(Element) != XML_linkedTxbx) && (oox::getBaseToken(Element) != XML_txbx);
1947
1948 if ( bInNamespaces && ((!bIsWrap && !bIsSignatureLine)
1949 || mxShapeHandler->isShapeSent()) )
1950 {
1951 xResult.set(OOXMLFactory::createFastChildContextFromStart(this, Element));
1952 }
1953 else if (mxWrappedContext.is() && !bSkipImages)
1954 {
1955 OOXMLFastContextHandlerWrapper * pWrapper =
1956 new OOXMLFastContextHandlerWrapper
1957 (this, mxWrappedContext->createFastChildContext(Element, Attribs),
1958 mxShapeHandler);
1959 pWrapper->mMyNamespaces = mMyNamespaces;
1960 pWrapper->mMyTokens = mMyTokens;
1961 pWrapper->setPropertySet(getPropertySet());
1962 xResult.set(pWrapper);
1963 }
1964 else
1965 {
1966 xResult.set(this);
1967 }
1968
1969 if ( bInTokens )
1970 mxShapeHandler->sendShape( Element );
1971
1972 return xResult;
1973}
1974
1975void OOXMLFastContextHandlerWrapper::lcl_characters
1976(const OUString & aChars)
1977{
1978 if (mxWrappedContext.is())
1979 mxWrappedContext->characters(aChars);
1980}
1981
1982OOXMLFastContextHandler *
1983OOXMLFastContextHandlerWrapper::getFastContextHandler() const
1984{
1985 if (mxWrappedContext.is())
1986 return dynamic_cast<OOXMLFastContextHandler *>(mxWrappedContext.get());
1987
1988 return nullptr;
1989}
1990
1991void OOXMLFastContextHandlerWrapper::newProperty
1992(Id nId, const OOXMLValue::Pointer_t& pVal)
1993{
1994 if (mxWrappedContext.is())
1995 {
1996 OOXMLFastContextHandler * pHandler = getFastContextHandler();
1997 if (pHandler != nullptr)
1998 pHandler->newProperty(nId, pVal);
1999 }
2000}
2001
2002void OOXMLFastContextHandlerWrapper::setPropertySet
2003(const OOXMLPropertySet::Pointer_t& pPropertySet)
2004{
2005 if (mxWrappedContext.is())
2006 {
2007 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2008 if (pHandler != nullptr)
2009 pHandler->setPropertySet(pPropertySet);
2010 }
2011
2012 mpPropertySet = pPropertySet;
2013}
2014
2015OOXMLPropertySet::Pointer_t OOXMLFastContextHandlerWrapper::getPropertySet()
2016 const
2017{
2018 OOXMLPropertySet::Pointer_t pResult(mpPropertySet);
2019
2020 if (mxWrappedContext.is())
2021 {
2022 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2023 if (pHandler != nullptr)
2024 pResult = pHandler->getPropertySet();
2025 }
2026
2027 return pResult;
2028}
2029
2030string OOXMLFastContextHandlerWrapper::getType() const
2031{
2032 string sResult = "Wrapper(";
2033
2034 if (mxWrappedContext.is())
2035 {
2036 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2037 if (pHandler != nullptr)
2038 sResult += pHandler->getType();
2039 }
2040
2041 sResult += ")";
2042
2043 return sResult;
2044}
2045
2046void OOXMLFastContextHandlerWrapper::setId(Id rId)
2047{
2048 OOXMLFastContextHandler::setId(rId);
2049
2050 if (mxWrappedContext.is())
2051 {
2052 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2053 if (pHandler != nullptr)
2054 pHandler->setId(rId);
2055 }
2056}
2057
2058Id OOXMLFastContextHandlerWrapper::getId() const
2059{
2060 Id nResult = OOXMLFastContextHandler::getId();
2061
2062 if (mxWrappedContext.is())
2063 {
2064 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2065 if (pHandler != nullptr && pHandler->getId() != 0)
2066 nResult = pHandler->getId();
2067 }
2068
2069 return nResult;
2070}
2071
2072void OOXMLFastContextHandlerWrapper::setToken(Token_t nToken)
2073{
2074 OOXMLFastContextHandler::setToken(nToken);
2075
2076 if (mxWrappedContext.is())
2077 {
2078 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2079 if (pHandler != nullptr)
2080 pHandler->setToken(nToken);
2081 }
2082}
2083
2084Token_t OOXMLFastContextHandlerWrapper::getToken() const
2085{
2086 Token_t nResult = OOXMLFastContextHandler::getToken();
2087
2088 if (mxWrappedContext.is())
2089 {
2090 OOXMLFastContextHandler * pHandler = getFastContextHandler();
2091 if (pHandler != nullptr)
2092 nResult = pHandler->getToken();
2093 }
2094
2095 return nResult;
2096}
2097
2098
2099/*
2100 class OOXMLFastContextHandlerLinear
2101 */
2102
2103OOXMLFastContextHandlerLinear::OOXMLFastContextHandlerLinear(OOXMLFastContextHandler* pContext)
2104 : OOXMLFastContextHandlerProperties(pContext)
2105 , depthCount( 0 )
2106{
2107}
2108
2109void OOXMLFastContextHandlerLinear::lcl_startFastElement(Token_t Element,
2110 const uno::Reference< xml::sax::XFastAttributeList >& Attribs)
2111{
2112 buffer.appendOpeningTag( Element, Attribs );
2113 ++depthCount;
2114}
2115
2116void OOXMLFastContextHandlerLinear::lcl_endFastElement(Token_t Element)
2117{
2118 buffer.appendClosingTag( Element );
2119 if( --depthCount == 0 )
2120 process();
2121}
2122
2123uno::Reference< xml::sax::XFastContextHandler >
2124OOXMLFastContextHandlerLinear::lcl_createFastChildContext(Token_t,
2125 const uno::Reference< xml::sax::XFastAttributeList >&)
2126{
2127 uno::Reference< xml::sax::XFastContextHandler > xContextHandler;
2128 xContextHandler.set( this );
2129 return xContextHandler;
2130}
2131
2132void OOXMLFastContextHandlerLinear::lcl_characters(const OUString& aChars)
2133{
2134 buffer.appendCharacters( aChars );
2135}
2136
2137/*
2138 class OOXMLFastContextHandlerLinear
2139 */
2140
2141OOXMLFastContextHandlerMath::OOXMLFastContextHandlerMath(OOXMLFastContextHandler* pContext)
2142 : OOXMLFastContextHandlerLinear(pContext)
2143{
2144}
2145
2146void OOXMLFastContextHandlerMath::process()
2147{
2148 SvGlobalName name( SO3_SM_CLASSID0x078B7ABA, 0x54FC, 0x457F, 0x85, 0x51, 0x61, 0x47, 0xE7, 0x76
, 0xA9, 0x97
);
2149 comphelper::EmbeddedObjectContainer container;
2150 OUString aName;
2151 uno::Sequence<beans::PropertyValue> objArgs(1);
2152 objArgs[0].Name = "DefaultParentBaseURL";
2153 objArgs[0].Value <<= getDocument()->GetDocumentBaseURL();
2154 uno::Reference<embed::XEmbeddedObject> ref =
2155 container.CreateEmbeddedObject(name.GetByteSequence(), objArgs, aName);
2156 assert(ref.is())(static_cast <bool> (ref.is()) ? void (0) : __assert_fail
("ref.is()", "/home/maarten/src/libreoffice/core/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx"
, 2156, __extension__ __PRETTY_FUNCTION__))
;
2157 if (!ref.is())
2158 return;
2159 uno::Reference< uno::XInterface > component(ref->getComponent(), uno::UNO_QUERY_THROW);
2160// gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
2161// so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
2162// to RTLD_GLOBAL, so most probably a gcc bug.
2163 oox::FormulaImportBase& import = dynamic_cast<oox::FormulaImportBase&>(dynamic_cast<SfxBaseModel&>(*component));
2164 import.readFormulaOoxml(buffer);
2165 if (!isForwardEvents())
2166 return;
2167
2168 OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
2169 OOXMLValue::Pointer_t pVal( new OOXMLStarMathValue( ref ));
2170 if (mbIsMathPara)
2171 {
2172 switch (mnMathJcVal)
2173 {
2174 case eMathParaJc::CENTER:
2175 pProps->add(NS_ooxml::LN_Value_math_ST_Jc_centerGroup, pVal,
2176 OOXMLProperty::ATTRIBUTE);
2177 break;
2178 case eMathParaJc::LEFT:
2179 pProps->add(NS_ooxml::LN_Value_math_ST_Jc_left, pVal,
2180 OOXMLProperty::ATTRIBUTE);
2181 break;
2182 case eMathParaJc::RIGHT:
2183 pProps->add(NS_ooxml::LN_Value_math_ST_Jc_right, pVal,
2184 OOXMLProperty::ATTRIBUTE);
2185 break;
2186 default:
2187 break;
2188 }
2189 }
2190 else
2191 pProps->add(NS_ooxml::LN_starmath, pVal, OOXMLProperty::ATTRIBUTE);
2192 mpStream->props( pProps.get() );
2193}
2194
2195}
2196
2197/* vim:set shiftwidth=4 softtabstop=4 expandtab: */