[Libreoffice-commits] core.git: sax/source

Caolán McNamara caolanm at redhat.com
Thu Nov 30 08:56:11 UTC 2017


 sax/source/fastparser/fastparser.cxx |  156 +++++++++++++++++------------------
 1 file changed, 77 insertions(+), 79 deletions(-)

New commits:
commit 5591aa360874c9133d046eeaa1c315df1a441bc4
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Nov 29 21:18:11 2017 +0000

    ofz: always free with xmlFreeParserCtxt
    
    Change-Id: I90aed11ae0a29a0e9fc725b297e10a7ed30c9942
    Reviewed-on: https://gerrit.libreoffice.org/45533
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx
index 8c0286656764..1aa8811366ea 100644
--- a/sax/source/fastparser/fastparser.cxx
+++ b/sax/source/fastparser/fastparser.cxx
@@ -730,6 +730,27 @@ sal_Int32 FastSaxParserImpl::GetTokenWithContextNamespace( sal_Int32 nNamespaceT
     return FastToken::DONTKNOW;
 }
 
+namespace
+{
+    class ParserCleanup
+    {
+    private:
+        FastSaxParserImpl& m_rParser;
+        Entity& m_rEntity;
+    public:
+        ParserCleanup(FastSaxParserImpl& rParser, Entity& rEntity)
+            : m_rParser(rParser)
+            , m_rEntity(rEntity)
+        {
+        }
+        ~ParserCleanup()
+        {
+            //xmlFreeParserCtxt accepts a null arg
+            xmlFreeParserCtxt(m_rEntity.mpParser);
+            m_rParser.popEntity();
+        }
+    };
+}
 /***************
 *
 * parseStream does Parser-startup initializations. The FastSaxParser::parse() method does
@@ -755,104 +776,81 @@ void FastSaxParserImpl::parseStream(const InputSource& maStructSource)
 
     pushEntity( entity );
     Entity& rEntity = getEntity();
-    try
+    ParserCleanup aEnsureFree(*this, rEntity);
+
+    // start the document
+    if( rEntity.mxDocumentHandler.is() )
     {
-        // start the document
-        if( rEntity.mxDocumentHandler.is() )
-        {
-            Reference< XLocator > xLoc( mxDocumentLocator.get() );
-            rEntity.mxDocumentHandler->setDocumentLocator( xLoc );
-            rEntity.mxDocumentHandler->startDocument();
-        }
+        Reference< XLocator > xLoc( mxDocumentLocator.get() );
+        rEntity.mxDocumentHandler->setDocumentLocator( xLoc );
+        rEntity.mxDocumentHandler->startDocument();
+    }
 
-        rEntity.mbEnableThreads = rEntity.maStructSource.aInputStream->available() > 10000
-            && !getenv("SAX_DISABLE_THREADS");
+    rEntity.mbEnableThreads = rEntity.maStructSource.aInputStream->available() > 10000
+        && !getenv("SAX_DISABLE_THREADS");
 
-        if (rEntity.mbEnableThreads)
-        {
-            rtl::Reference<ParserThread> xParser;
-            xParser = new ParserThread(this);
-            xParser->launch();
-            bool done = false;
-            do {
-                rEntity.maConsumeResume.wait();
-                rEntity.maConsumeResume.reset();
-
-                osl::ResettableMutexGuard aGuard(rEntity.maEventProtector);
-                while (!rEntity.maPendingEvents.empty())
-                {
-                    if (rEntity.maPendingEvents.size() <= Entity::mnEventLowWater)
-                        rEntity.maProduceResume.set(); // start producer again
+    if (rEntity.mbEnableThreads)
+    {
+        rtl::Reference<ParserThread> xParser;
+        xParser = new ParserThread(this);
+        xParser->launch();
+        bool done = false;
+        do {
+            rEntity.maConsumeResume.wait();
+            rEntity.maConsumeResume.reset();
+
+            osl::ResettableMutexGuard aGuard(rEntity.maEventProtector);
+            while (!rEntity.maPendingEvents.empty())
+            {
+                if (rEntity.maPendingEvents.size() <= Entity::mnEventLowWater)
+                    rEntity.maProduceResume.set(); // start producer again
 
-                    std::unique_ptr<EventList> xEventList = std::move(rEntity.maPendingEvents.front());
-                    rEntity.maPendingEvents.pop();
-                    aGuard.clear(); // unlock
+                std::unique_ptr<EventList> xEventList = std::move(rEntity.maPendingEvents.front());
+                rEntity.maPendingEvents.pop();
+                aGuard.clear(); // unlock
 
-                    if (!consume(*xEventList))
-                        done = true;
+                if (!consume(*xEventList))
+                    done = true;
 
-                    aGuard.reset(); // lock
+                aGuard.reset(); // lock
 
-                    if ( rEntity.maPendingEvents.size() <= Entity::mnEventLowWater )
+                if ( rEntity.maPendingEvents.size() <= Entity::mnEventLowWater )
+                {
+                    aGuard.clear();
+                    for (auto aEventIt = xEventList->maEvents.begin();
+                        aEventIt != xEventList->maEvents.end(); ++aEventIt)
                     {
-                        aGuard.clear();
-                        for (auto aEventIt = xEventList->maEvents.begin();
-                            aEventIt != xEventList->maEvents.end(); ++aEventIt)
+                        if (aEventIt->mxAttributes.is())
                         {
-                            if (aEventIt->mxAttributes.is())
-                            {
-                                aEventIt->mxAttributes->clear();
-                                if( rEntity.mxNamespaceHandler.is() )
-                                    aEventIt->mxDeclAttributes->clear();
-                            }
-                            xEventList->mbIsAttributesEmpty = true;
+                            aEventIt->mxAttributes->clear();
+                            if( rEntity.mxNamespaceHandler.is() )
+                                aEventIt->mxDeclAttributes->clear();
                         }
-                        aGuard.reset();
+                        xEventList->mbIsAttributesEmpty = true;
                     }
-
-                    rEntity.maUsedEvents.push(std::move(xEventList));
+                    aGuard.reset();
                 }
-            } while (!done);
-            xParser->join();
-            deleteUsedEvents();
 
-            // callbacks used inside XML_Parse may have caught an exception
-            if( rEntity.maSavedException.hasValue() )
-                rEntity.throwException( mxDocumentLocator, true );
-        }
-        else
-        {
-            parse();
-        }
+                rEntity.maUsedEvents.push(std::move(xEventList));
+            }
+        } while (!done);
+        xParser->join();
+        deleteUsedEvents();
 
-        // finish document
-        if( rEntity.mxDocumentHandler.is() )
-        {
-            rEntity.mxDocumentHandler->endDocument();
-        }
-    }
-    catch (const SAXException&)
-    {
-        // TODO free mpParser.myDoc ?
-        xmlFreeParserCtxt( rEntity.mpParser );
-        popEntity();
-        throw;
+        // callbacks used inside XML_Parse may have caught an exception
+        if( rEntity.maSavedException.hasValue() )
+            rEntity.throwException( mxDocumentLocator, true );
     }
-    catch (const IOException&)
+    else
     {
-        xmlFreeParserCtxt( rEntity.mpParser );
-        popEntity();
-        throw;
+        parse();
     }
-    catch (const RuntimeException&)
+
+    // finish document
+    if( rEntity.mxDocumentHandler.is() )
     {
-        xmlFreeParserCtxt( rEntity.mpParser );
-        popEntity();
-        throw;
+        rEntity.mxDocumentHandler->endDocument();
     }
-
-    xmlFreeParserCtxt( rEntity.mpParser );
-    popEntity();
 }
 
 void FastSaxParserImpl::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler )


More information about the Libreoffice-commits mailing list