From 153ed9a70b37d76d850831e4011ee7063d182c69 Mon Sep 17 00:00:00 2001 From: randomdan Date: Fri, 27 Apr 2012 20:13:18 +0000 Subject: Fixed memory leak in HtmlDocument (free doc) Fix crash when internal transforms and debug document are enabled together (remove debug target transform from presenter) --- project2/cgi/cgiAppEngine.cpp | 16 +++++++++------- project2/common/transform.cpp | 6 ++++++ project2/common/transform.h | 1 + project2/xml/transformHtml.cpp | 14 +++++++++++++- project2/xml/transformHtml.h | 1 + 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index ea50627..566b979 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -138,26 +138,28 @@ CgiApplicationEngine::process() const } if (TransformSourcePtr ts = currentStage.get<2>()) { TransformSourcePtr final = finalTransformSource(ts); - ScopeObject emptyFinal(boost::bind(&TransformSource::clearTargets, final)); + ScopeObject emptyFinal([final] { final->clearTargets(); }); final->addTarget(new CgiResult(header, IO, rs && rs->root ? rs->root->value("encoding", _env->outputEncoding) : VariableType(_env->outputEncoding)), NULL); BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { final->addTarget(p, NULL); } - std::fstream * ddd = NULL; + boost::shared_ptr ddd; + ostreamWrapper * osw = NULL; + ScopeObject removeDdd([ts, &osw] { if (osw) { ts->removeTarget(osw); } }); if (!_env->dumpdatadoc.empty()) { - ddd = new std::fstream(_env->dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out); + ddd = boost::shared_ptr(new std::fstream(_env->dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out)); if (ddd->good()) { - ts->addTarget(new ostreamWrapper(*ddd)); + ts->addTarget(osw = new ostreamWrapper(*ddd)); + } + else { + ddd.reset(); } } ts->doTransforms(); BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { p->flushCache(); } - if (ddd) { - delete ddd; - } } else { header->render(IO); diff --git a/project2/common/transform.cpp b/project2/common/transform.cpp index 874ced3..5c67bd7 100644 --- a/project2/common/transform.cpp +++ b/project2/common/transform.cpp @@ -62,6 +62,12 @@ TransformSource::clearTargets() targets.clear(); } +void +TransformSource::removeTarget(TransformChainLinkPtr tcl) +{ + targets.erase(tcl); +} + void TransformSource::doTransforms() const { diff --git a/project2/common/transform.h b/project2/common/transform.h index b7a724a..973f4f0 100644 --- a/project2/common/transform.h +++ b/project2/common/transform.h @@ -21,6 +21,7 @@ class TransformSource : public TransformChainLink { TransformSource(); TransformSource(ScriptNodePtr); void clearTargets(); + void removeTarget(TransformChainLinkPtr); void addTarget(TransformChainLinkPtr, ScriptNodePtr e = NULL); void doTransforms() const; const Targets & getTargets() const; diff --git a/project2/xml/transformHtml.cpp b/project2/xml/transformHtml.cpp index e280f27..f032945 100644 --- a/project2/xml/transformHtml.cpp +++ b/project2/xml/transformHtml.cpp @@ -8,10 +8,18 @@ HtmlDocument::HtmlDocument(ScriptNodePtr s) : TransformSource(s), SourceOf(s), SourceOf(s), + doc(NULL), contentType(s, "contenttype", "text/html") { } +HtmlDocument::~HtmlDocument() +{ + if (doc) { + xmlFreeDoc(doc); + } +} + HtmlDocument::operator const HtmlDocument * () const { return this; } HtmlDocument::operator const WritableContent * () const { return this; } @@ -55,8 +63,12 @@ class TransformXmlToHtml : public TransformImpl { if (!cur) { throw xmlpp::exception("Failed to load stylesheet"); } + if (result->doc) { + xmlFreeDoc(result->doc); + result->doc = NULL; + } result->doc = xsltApplyStylesheet(cur.get(), data->cobj(), NULL); - if (!result) { + if (!result->doc) { throw xmlpp::exception("Failed to perform transformation"); } } diff --git a/project2/xml/transformHtml.h b/project2/xml/transformHtml.h index b8d4207..6ff5d91 100644 --- a/project2/xml/transformHtml.h +++ b/project2/xml/transformHtml.h @@ -7,6 +7,7 @@ class HtmlDocument : public SourceOf, public WritableContent, public SourceOf { public: HtmlDocument(ScriptNodePtr); + ~HtmlDocument(); htmlDocPtr doc; operator const HtmlDocument * () const; operator const WritableContent * () const; -- cgit v1.2.3