diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-05-09 01:14:49 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-05-09 01:14:49 +0100 |
commit | 5e89fa46f8f90015f47210d9f532fb8626db8d17 (patch) | |
tree | 2e3dcacbb1183e8b3de132a83c9d88bf3156d58f | |
parent | Fix leak of html/xml document structure (diff) | |
download | project2-1.2.6.tar.bz2 project2-1.2.6.tar.xz project2-1.2.6.zip |
Remove implicit cast to char * because it's dangerous as everyone knowsproject2-1.2.6
-rw-r--r-- | project2/basics/functions/dates.cpp | 10 | ||||
-rw-r--r-- | project2/basics/options/preload.cpp | 7 | ||||
-rw-r--r-- | project2/basics/tests/validDateCheck.cpp | 12 | ||||
-rw-r--r-- | project2/common/variableConvert.cpp | 32 | ||||
-rw-r--r-- | project2/common/variableType.h | 2 | ||||
-rw-r--r-- | project2/daemon/p2daemonAppEngine.cpp | 4 | ||||
-rw-r--r-- | project2/files/fileStream.cpp | 2 | ||||
-rw-r--r-- | project2/mail/sendmailTask.cpp | 10 | ||||
-rw-r--r-- | project2/sql/sqlBulkLoad.cpp | 4 | ||||
-rw-r--r-- | project2/url/curlHelper.cpp | 21 | ||||
-rw-r--r-- | project2/url/curlHelper.h | 3 | ||||
-rw-r--r-- | project2/url/downloadToFile.cpp | 4 | ||||
-rw-r--r-- | project2/xml/xmlPresenter.cpp | 4 | ||||
-rw-r--r-- | project2/xml/xmlRows.cpp | 2 | ||||
-rw-r--r-- | project2/xml/xpathRows.cpp | 7 |
15 files changed, 55 insertions, 69 deletions
diff --git a/project2/basics/functions/dates.cpp b/project2/basics/functions/dates.cpp index 91a7077..90708d3 100644 --- a/project2/basics/functions/dates.cpp +++ b/project2/basics/functions/dates.cpp @@ -18,14 +18,14 @@ class ParseDate : public VariableImpl { } VariableType value(ExecContext * ec) const { - const char * s = string(ec); - const char * f = format(ec); + const std::string s = string(ec); + const std::string f = format(ec); struct tm tm; memset(&tm, 0, sizeof(struct tm)); mktime(&tm); - const char * e = strptime(s, f, &tm); + const char * e = strptime(s.c_str(), f.c_str(), &tm); if (!e || *e) { - Logger()->messagef(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')", + Logger()->messagebf(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')", __PRETTY_FUNCTION__, s, f, e); throw DateParseError(string(ec), format(ec)); } @@ -49,7 +49,7 @@ class FormatDate : public VariableImpl { std::stringstream ss; boost::date_time::time_facet<boost::posix_time::ptime, char> * ft = new boost::date_time::time_facet<boost::posix_time::ptime, char>(); ss.imbue(std::locale(ss.getloc(), ft)); - ft->format(format(ec)); + ft->format(format(ec).as<std::string>().c_str()); ss << boost::get<boost::posix_time::ptime>(date(ec)); return ss.str(); } diff --git a/project2/basics/options/preload.cpp b/project2/basics/options/preload.cpp index 4781abb..506be1d 100644 --- a/project2/basics/options/preload.cpp +++ b/project2/basics/options/preload.cpp @@ -21,13 +21,14 @@ class Preload { { const auto beforeOpts = AdHoc::PluginManager::getDefault()->getAll<Options>(); - void * handle = dlopen(librarypath, RTLD_GLOBAL | RTLD_NOW); + std::string path(librarypath.as<std::string>()); + void * handle = dlopen(path.c_str(), RTLD_GLOBAL | RTLD_NOW); if (handle) { - Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", librarypath.as<std::string>()); + Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", path); } else { const char * dlerr = dlerror(); - Logger()->messagebf(LOG_ERR, "Failed to load library '%s' (%s)", librarypath.as<std::string>(), dlerr); + Logger()->messagebf(LOG_ERR, "Failed to load library '%s' (%s)", path, dlerr); throw LoadLibraryFailed(librarypath, dlerr); } libs[librarypath.as<std::string>()] = boost::shared_ptr<void>(handle, &dlclose); diff --git a/project2/basics/tests/validDateCheck.cpp b/project2/basics/tests/validDateCheck.cpp index 231a478..a17933f 100644 --- a/project2/basics/tests/validDateCheck.cpp +++ b/project2/basics/tests/validDateCheck.cpp @@ -27,17 +27,17 @@ class ValidDateTest : public Test { struct tm tm, ftm; memset(&tm, 0, sizeof(struct tm)); mktime(&tm); - const char * at = applyTo(ec); - const char * f = format(ec); - const char * s = strptime(at, f, &tm); + const std::string at = applyTo(ec); + const std::string f = format(ec); + const char * s = strptime(at.c_str(), f.c_str(), &tm); if (!s || *s) { - Logger()->messagef(warnLev, "%s: check failed (parse) for '%s' against '%s'", + Logger()->messagebf(warnLev, "%s: check failed (parse) for '%s' against '%s'", __PRETTY_FUNCTION__, at, f); return false; } ftm = tm; if (mktime(&ftm) == -1) { - Logger()->messagef(warnLev, "%s: check failed (normalise) for '%s' against '%s'", + Logger()->messagebf(warnLev, "%s: check failed (normalise) for '%s' against '%s'", __PRETTY_FUNCTION__, at, f); return false; } @@ -51,7 +51,7 @@ class ValidDateTest : public Test { tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); Logger()->messagef(LOG_INFO, "ftm: %d %d %d %d %d %d", ftm.tm_year, ftm.tm_mon, ftm.tm_mday, ftm.tm_hour, ftm.tm_min, ftm.tm_sec); - Logger()->messagef(warnLev, "%s: check failed (verify) for '%s' against '%s'", + Logger()->messagebf(warnLev, "%s: check failed (verify) for '%s' against '%s'", __PRETTY_FUNCTION__, at, f); return false; } diff --git a/project2/common/variableConvert.cpp b/project2/common/variableConvert.cpp index fb90c95..0681ed0 100644 --- a/project2/common/variableConvert.cpp +++ b/project2/common/variableConvert.cpp @@ -70,30 +70,6 @@ class ConvertVisitorStdString : public boost::static_visitor<const std::string & private: const VariableType * var; }; -// Convert to char * (with std::string storage) -class ConvertVisitorCharStar : public boost::static_visitor<const char *> { - public: - ConvertVisitorCharStar(const VariableType * v) : var(v) { - } - const char * operator()(const Glib::ustring & r) const { - return r.c_str(); - } - const char * operator()(const boost::posix_time::time_duration & r) const { - CONVERTF(const Glib::ustring, boost::posix_time::to_simple_string, c_str); - } - const char * operator()(const boost::posix_time::ptime & r) const { - CONVERTF(const Glib::ustring, boost::posix_time::to_iso_extended_string, c_str); - } - const char * operator()(const Null &) const { - return NULL; - } - template <typename T> - const char * operator()(const T & r) const { - CONVERTF(const Glib::ustring, boost::lexical_cast<Glib::ustring>, c_str); - } - private: - const VariableType * var; -}; // Convert to numeric type template <typename DestType> class ConvertVisitor : public boost::static_visitor<DestType> { @@ -203,14 +179,6 @@ VariableType::operator const std::string &() const { return boost::apply_visitor(ConvertVisitorStdString(this), *this); } -VariableType::operator const char *() const -{ - return boost::apply_visitor(ConvertVisitorCharStar(this), *this); -} -VariableType::operator const unsigned char *() const -{ - return reinterpret_cast<const unsigned char *>(boost::apply_visitor(ConvertVisitorCharStar(this), *this)); -} VariableType::operator int() const { return boost::apply_visitor(ConvertVisitor<int>(this), *this); diff --git a/project2/common/variableType.h b/project2/common/variableType.h index b395a41..0e3cc0a 100644 --- a/project2/common/variableType.h +++ b/project2/common/variableType.h @@ -93,8 +93,6 @@ class DLL_PUBLIC VariableType : public _VT { operator const Glib::ustring &() const; operator const std::string &() const; - operator const char *() const; - operator const unsigned char *() const; operator long long int() const; operator long int() const; operator int() const; diff --git a/project2/daemon/p2daemonAppEngine.cpp b/project2/daemon/p2daemonAppEngine.cpp index 27dff10..9634ec8 100644 --- a/project2/daemon/p2daemonAppEngine.cpp +++ b/project2/daemon/p2daemonAppEngine.cpp @@ -30,7 +30,7 @@ DECLARE_OPTIONS(DaemonAppEngine, "Project2 Daemon options") ("daemon.periodicTimeout", Options::value(&periodicTimeout, 60), "Delay between occurrences of component periodic calls (default 60s)") ("daemon.setuser", Options::functions([](const VariableType & un) { - auto passwd = getpwnam(un); + auto passwd = getpwnam(un.as<std::string>().c_str()); if (!passwd) { throw NoSuchUser(un); } @@ -38,7 +38,7 @@ DECLARE_OPTIONS(DaemonAppEngine, "Project2 Daemon options") }, []{ setUser = boost::optional<uid_t>(); }), "Switch to this user on start up") ("daemon.setgroup", Options::functions([](const VariableType & gn) { - auto group = getgrnam(gn); + auto group = getgrnam(gn.as<std::string>().c_str()); if (!group) { throw NoSuchGroup(gn); } diff --git a/project2/files/fileStream.cpp b/project2/files/fileStream.cpp index ddfa30b..6361438 100644 --- a/project2/files/fileStream.cpp +++ b/project2/files/fileStream.cpp @@ -23,7 +23,7 @@ class FileStream : public Stream { void runStream(const Sink & sink, ExecContext * ec) const override { - FILE * file = fopen(path(ec), "r"); + FILE * file = fopen(path(ec).as<std::string>().c_str(), "r"); if (!file) { throw syscall_error(errno); } diff --git a/project2/mail/sendmailTask.cpp b/project2/mail/sendmailTask.cpp index 5442887..a201142 100644 --- a/project2/mail/sendmailTask.cpp +++ b/project2/mail/sendmailTask.cpp @@ -107,8 +107,8 @@ class Header : public SendMailTask::MailPart { return (const char *)*buf; } private: - void writeText(char ** buf, int * len, const char * text) const { - *len = asprintf(buf, "%s: %s\r\n", header.c_str(), text); + void writeText(char ** buf, int * len, const std::string & text) const { + *len = asprintf(buf, "%s: %s\r\n", header.c_str(), text.c_str()); } const std::string header; const VariableType value; @@ -201,9 +201,11 @@ SendMailTask::execute(ExecContext * ec) const // Write email smtp_session_t session = smtp_create_session(); smtp_message_t message = smtp_add_message(session); - smtp_set_server(session, server(ec)); + std::string svr(server(ec)); + std::string t(to(ec)); + smtp_set_server(session, svr.c_str()); smtp_set_header(message, "To", NULL, NULL); - smtp_add_recipient(message, to(ec)); + smtp_add_recipient(message, t.c_str()); smtp_set_messagecb(message, writeMail, parts.get()); if (!smtp_start_session(session)) { char buf[BUFSIZ]; diff --git a/project2/sql/sqlBulkLoad.cpp b/project2/sql/sqlBulkLoad.cpp index f905a68..96a590e 100644 --- a/project2/sql/sqlBulkLoad.cpp +++ b/project2/sql/sqlBulkLoad.cpp @@ -21,7 +21,9 @@ class SqlBulkLoad : public Task, SqlBase { void execute(ExecContext * ec) const { auto wdb = db->getWritable(); - wdb->beginBulkUpload(targetTable(ec), extras(ec)); + const std::string tt(targetTable(ec)); + const std::string x(extras(ec)); + wdb->beginBulkUpload(tt.c_str(), x.c_str()); AdHoc::ScopeExit tidy([]{}, [&]{ wdb->endBulkUpload(NULL); }, [&]{ wdb->endBulkUpload("Stack unwind in progress"); }); diff --git a/project2/url/curlHelper.cpp b/project2/url/curlHelper.cpp index bd331e8..c38f5aa 100644 --- a/project2/url/curlHelper.cpp +++ b/project2/url/curlHelper.cpp @@ -46,14 +46,25 @@ void VariableCurlHelper::setCurlOpts(AdHoc::Net::CurlHandle * c, ExecContext * ec) const { CurlHelper::setCurlOpts(c, ec); - c->setopt<const char *>(CURLOPT_USERAGENT, userAgent(ec)); - c->setopt<const char *>(CURLOPT_PROXY, proxy(ec)); - c->setopt<const char *>(CURLOPT_REFERER, referer(ec)); - c->setopt<const char *>(CURLOPT_COOKIEFILE, cookieJar(ec)); - c->setopt<const char *>(CURLOPT_COOKIEJAR, cookieJar(ec)); + setCurlOptCached(c, CURLOPT_USERAGENT, userAgent, ec); + setCurlOptCached(c, CURLOPT_PROXY, proxy, ec); + setCurlOptCached(c, CURLOPT_REFERER, referer, ec); + setCurlOptCached(c, CURLOPT_COOKIEFILE, cookieJar, ec); + setCurlOptCached(c, CURLOPT_COOKIEJAR, cookieJar, ec); c->setopt<long>(CURLOPT_TIMEOUT_MS, timeout(ec)); } +void +VariableCurlHelper::setCurlOptCached(AdHoc::Net::CurlHandle * c, CURLoption opt, const Variable & v, ExecContext * ec) const +{ + if (v(ec).isNull()) { + c->setopt(opt, nullptr); + } + else { + c->setopt(opt, valueCache.insert(ValueCache::value_type(opt, v(ec))).first->second.c_str()); + } +} + std::string VariableCurlHelper::getUrl(ExecContext * ec) const { diff --git a/project2/url/curlHelper.h b/project2/url/curlHelper.h index ff1947b..66e7643 100644 --- a/project2/url/curlHelper.h +++ b/project2/url/curlHelper.h @@ -28,6 +28,7 @@ class DLL_PUBLIC VariableCurlHelper : public CurlHelper { protected: virtual void setCurlOpts(AdHoc::Net::CurlHandle *, ExecContext *) const override; + void setCurlOptCached(AdHoc::Net::CurlHandle *, CURLoption, const Variable &, ExecContext * ec) const; virtual std::string getUrl(ExecContext *) const override; private: @@ -39,6 +40,8 @@ class DLL_PUBLIC VariableCurlHelper : public CurlHelper { const Variable userName; const Variable password; const Variable timeout; + typedef std::map<CURLoption, std::string> ValueCache; + mutable ValueCache valueCache; }; #endif diff --git a/project2/url/downloadToFile.cpp b/project2/url/downloadToFile.cpp index 1d73cce..0c91f91 100644 --- a/project2/url/downloadToFile.cpp +++ b/project2/url/downloadToFile.cpp @@ -14,10 +14,10 @@ class Download : public Task, VariableCurlHelper { destination(p, "destination") { } - + void execute(ExecContext * ec) const { - FILE * file = fopen(destination(ec), "w"); + FILE * file = fopen(destination(ec).as<std::string>().c_str(), "w"); if (!file) { throw syscall_error(errno); } diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp index ec3d637..59543e0 100644 --- a/project2/xml/xmlPresenter.cpp +++ b/project2/xml/xmlPresenter.cpp @@ -85,7 +85,7 @@ XmlPresenter::init(ExecContext * ec) // XSLT Style char * buf; if (!style(ec).isNull() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"", - style(ec).as<const char *>()) > 0) { + style(ec).as<std::string>().c_str()) > 0) { xmlAddPrevSibling(nodeStack.back()->cobj(), xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf)); free(buf); @@ -198,7 +198,7 @@ class XmlNodeWriter : public boost::static_visitor<bool> { } if (!dateFormat.isNull()) { std::stringstream ss; - boost::posix_time::time_facet ft(dateFormat.as<const char *>()); + boost::posix_time::time_facet ft(dateFormat.as<std::string>().c_str()); ft.put(ss, ss, ' ', i); node->set_attribute("custom", ss.str()); } diff --git a/project2/xml/xmlRows.cpp b/project2/xml/xmlRows.cpp index 1c08159..aa1d0aa 100644 --- a/project2/xml/xmlRows.cpp +++ b/project2/xml/xmlRows.cpp @@ -61,7 +61,7 @@ store(const XmlRows::Path & position, RowState::FieldValues & values, const XmlR void XmlRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const { - xmlTextReaderPtr reader = xmlReaderForFile(filename(ec), NULL, 0); + xmlTextReaderPtr reader = xmlReaderForFile(filename(ec).as<std::string>().c_str(), NULL, 0); if (reader == NULL) { throw std::runtime_error("Failed to open file"); } diff --git a/project2/xml/xpathRows.cpp b/project2/xml/xpathRows.cpp index 01f2e13..10ae2f4 100644 --- a/project2/xml/xpathRows.cpp +++ b/project2/xml/xpathRows.cpp @@ -62,11 +62,12 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp for (const Namespaces::value_type & ns : namespaces) { xmlXPathRegisterNs(xpathCtx.get(), BAD_CAST ns.first.c_str(), BAD_CAST ns.second.c_str()); } - xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(fv->root(ec), xpathCtx.get()), xmlXPathFreeObject); + Glib::ustring rootv(fv->root(ec).as<Glib::ustring>()); + xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(BAD_CAST rootv.c_str(), xpathCtx.get()), xmlXPathFreeObject); if (!xpathObj || !xpathObj->nodesetval) { throw XpathEvalError(xmlGetLastError()->message); } - Logger()->messagef(LOG_INFO, "%d nodes matched %s", xpathObj->nodesetval->nodeNr, (const char *)(fv->root(ec))); + Logger()->messagef(LOG_INFO, "%d nodes matched %s", xpathObj->nodesetval->nodeNr, rootv.c_str()); XPathState xs(fv); for (int row = 0; row < xpathObj->nodesetval->nodeNr; row += 1) { xmlNodePtr rowRoot = xpathObj->nodesetval->nodeTab[row]; @@ -77,7 +78,7 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp if (path.isNull()) { continue; } - xmlXPathObjectSPtr xpathObjI = xmlXPathObjectSPtr(xmlXPathEvalExpression(path, xpathCtx.get()), xmlXPathFreeObject); + xmlXPathObjectSPtr xpathObjI = xmlXPathObjectSPtr(xmlXPathEvalExpression(BAD_CAST path.as<std::string>().c_str(), xpathCtx.get()), xmlXPathFreeObject); if (!xpathObjI) { throw XpathEvalError(xmlGetLastError()->message); } |