filter/source/xsltfilter/LibXSLTTransformer.cxx | 26 ++++++--- filter/source/xsltfilter/LibXSLTTransformer.hxx | 69 +++++++++++------------- 2 files changed, 53 insertions(+), 42 deletions(-)
New commits: commit bce5cdcc7f59da19c063205c6c79fc30874cb5ee Author: Caolán McNamara <caol...@redhat.com> Date: Mon May 30 17:47:06 2016 +0100 Resolves: tdf#100057 force libxslt to give up when we cancel a transformation we're already using libxslt internals, so using XSLT_STATE_STOPPED isn't an additional exposure This probably isn't all that useful to the original reporter in terms of importing useful data, but it does turn a hopeless situation into something that can be cancelled. Change-Id: I08e9a1dcd9ee78e1804faec500bbcca36a546988 (cherry picked from commit 2805adb0d3cf68d7def01a93bf07fb2e8121ec10) diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx b/filter/source/xsltfilter/LibXSLTTransformer.cxx index 3dbe7a4..55f1920 100644 --- a/filter/source/xsltfilter/LibXSLTTransformer.cxx +++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx @@ -203,7 +203,8 @@ namespace XSLT Reader::Reader(LibXSLTTransformer* transformer) : Thread("LibXSLTTransformer"), m_transformer(transformer), - m_readBuf(INPUT_BUFFER_SIZE), m_writeBuf(OUTPUT_BUFFER_SIZE) + m_readBuf(INPUT_BUFFER_SIZE), m_writeBuf(OUTPUT_BUFFER_SIZE), + m_tcontext(nullptr) { LIBXML_TEST_VERSION; } @@ -288,7 +289,6 @@ namespace XSLT xsltStylesheetPtr styleSheet = xsltParseStylesheetFile( reinterpret_cast<const xmlChar *>(m_transformer->getStyleSheetURL().getStr())); xmlDocPtr result = nullptr; - xsltTransformContextPtr tcontext = nullptr; exsltRegisterAll(); registerExtensionModule(); #ifdef DEBUG_FILTER_LIBXSLTTRANSFORMER @@ -298,11 +298,11 @@ namespace XSLT std::unique_ptr<OleHandler> oh(new OleHandler(m_transformer->getComponentContext())); if (styleSheet) { - tcontext = xsltNewTransformContext(styleSheet, doc); - tcontext->_private = static_cast<void *> (oh.get()); - xsltQuoteUserParams(tcontext, ¶ms[0]); + m_tcontext = xsltNewTransformContext(styleSheet, doc); + m_tcontext->_private = static_cast<void *> (oh.get()); + xsltQuoteUserParams(m_tcontext, ¶ms[0]); result = xsltApplyStylesheetUser(styleSheet, doc, nullptr, nullptr, nullptr, - tcontext); + m_tcontext); } if (result) @@ -330,7 +330,8 @@ namespace XSLT closeOutput(); oh.reset(); xsltFreeStylesheet(styleSheet); - xsltFreeTransformContext(tcontext); + xsltFreeTransformContext(m_tcontext); + m_tcontext = nullptr; xmlFreeDoc(doc); xmlFreeDoc(result); } @@ -351,6 +352,16 @@ namespace XSLT } + void Reader::forceStateStopped() + { + if (!m_tcontext) + return; + //tdf#100057 If we force a cancel, libxslt will of course just keep on going unless something + //tells it to stop. Here we force the stopped state so that libxslt will stop processing + //and so Reader::execute will complete and we can join cleanly + m_tcontext->state = XSLT_STATE_STOPPED; + } + Reader::~Reader() { } @@ -455,6 +466,7 @@ namespace XSLT if (m_Reader.is()) { m_Reader->terminate(); + m_Reader->forceStateStopped(); m_Reader->join(); } m_Reader.clear(); diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx b/filter/source/xsltfilter/LibXSLTTransformer.hxx index d276018..9c4485b 100644 --- a/filter/source/xsltfilter/LibXSLTTransformer.hxx +++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx @@ -47,6 +47,36 @@ using ::std::map; namespace XSLT { + class LibXSLTTransformer; + + /* + * Reader provides a worker thread to perform the actual transformation. + * It pipes the streams provided by a LibXSLTTransformer + * instance through libxslt. + */ + class Reader : public salhelper::Thread + { + public: + Reader(LibXSLTTransformer* transformer); + int SAL_CALL read(char * buffer, int len); + int SAL_CALL write(const char * buffer, int len); + void forceStateStopped(); + int SAL_CALL closeOutput(); + + private: + virtual ~Reader(); + + static const sal_Int32 OUTPUT_BUFFER_SIZE; + static const sal_Int32 INPUT_BUFFER_SIZE; + LibXSLTTransformer* m_transformer; + Sequence<sal_Int8> m_readBuf; + Sequence<sal_Int8> m_writeBuf; + xsltTransformContextPtr m_tcontext; + + virtual void execute() override; + static void SAL_CALL registerExtensionModule(); + }; + /* * LibXSLTTransformer provides an transforming pipe service to XSLTFilter. * @@ -85,13 +115,14 @@ namespace XSLT ::std::map<const char *, OString> m_parameters; - rtl::Reference< salhelper::Thread > m_Reader; + rtl::Reference<Reader> m_Reader; protected: virtual ~LibXSLTTransformer() { if (m_Reader.is()) { - m_Reader->terminate(); - m_Reader->join(); + m_Reader->terminate(); + m_Reader->forceStateStopped(); + m_Reader->join(); } } @@ -144,39 +175,7 @@ namespace XSLT } }; - - /* - * Reader provides a worker thread to perform the actual transformation. - * It pipes the streams provided by a LibXSLTTransformer - * instance through libxslt. - */ - class Reader : public salhelper::Thread - { - public: - Reader(LibXSLTTransformer* transformer); - int SAL_CALL - read(char * buffer, int len); - int SAL_CALL - write(const char * buffer, int len); - int SAL_CALL - closeOutput(); - - private: - virtual - ~Reader(); - - static const sal_Int32 OUTPUT_BUFFER_SIZE; - static const sal_Int32 INPUT_BUFFER_SIZE; - LibXSLTTransformer* m_transformer; - Sequence<sal_Int8> m_readBuf; - Sequence<sal_Int8> m_writeBuf; - - virtual void execute() override; - static void SAL_CALL registerExtensionModule(); - }; - } -; #endif // INCLUDED_FILTER_SOURCE_XSLTFILTER_LIBXSLTTRANSFORMER_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits