summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2012-04-27 20:13:18 +0000
committerrandomdan <randomdan@localhost>2012-04-27 20:13:18 +0000
commit153ed9a70b37d76d850831e4011ee7063d182c69 (patch)
treeeea162316d53e96ecf9d4a3830057d44d9e40e49
parentCheck presenter caches are at least as new as their source scripts (bug17) (diff)
downloadproject2-153ed9a70b37d76d850831e4011ee7063d182c69.tar.bz2
project2-153ed9a70b37d76d850831e4011ee7063d182c69.tar.xz
project2-153ed9a70b37d76d850831e4011ee7063d182c69.zip
Fixed memory leak in HtmlDocument (free doc)
Fix crash when internal transforms and debug document are enabled together (remove debug target transform from presenter)
-rw-r--r--project2/cgi/cgiAppEngine.cpp16
-rw-r--r--project2/common/transform.cpp6
-rw-r--r--project2/common/transform.h1
-rw-r--r--project2/xml/transformHtml.cpp14
-rw-r--r--project2/xml/transformHtml.h1
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<std::fstream> 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<std::fstream>(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
@@ -63,6 +63,12 @@ TransformSource::clearTargets()
}
void
+TransformSource::removeTarget(TransformChainLinkPtr tcl)
+{
+ targets.erase(tcl);
+}
+
+void
TransformSource::doTransforms() const
{
BOOST_FOREACH(const Targets::value_type & t, targets) {
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<HtmlDocument>(s),
SourceOf<WritableContent>(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<xmlpp::Document, HtmlDocument> {
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<HtmlDocument>, public WritableContent, public SourceOf<WritableContent> {
public:
HtmlDocument(ScriptNodePtr);
+ ~HtmlDocument();
htmlDocPtr doc;
operator const HtmlDocument * () const;
operator const WritableContent * () const;