summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-05-09 01:14:49 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2016-05-09 01:14:49 +0100
commit5e89fa46f8f90015f47210d9f532fb8626db8d17 (patch)
tree2e3dcacbb1183e8b3de132a83c9d88bf3156d58f
parentFix leak of html/xml document structure (diff)
downloadproject2-5e89fa46f8f90015f47210d9f532fb8626db8d17.tar.bz2
project2-5e89fa46f8f90015f47210d9f532fb8626db8d17.tar.xz
project2-5e89fa46f8f90015f47210d9f532fb8626db8d17.zip
Remove implicit cast to char * because it's dangerous as everyone knowsproject2-1.2.6
-rw-r--r--project2/basics/functions/dates.cpp10
-rw-r--r--project2/basics/options/preload.cpp7
-rw-r--r--project2/basics/tests/validDateCheck.cpp12
-rw-r--r--project2/common/variableConvert.cpp32
-rw-r--r--project2/common/variableType.h2
-rw-r--r--project2/daemon/p2daemonAppEngine.cpp4
-rw-r--r--project2/files/fileStream.cpp2
-rw-r--r--project2/mail/sendmailTask.cpp10
-rw-r--r--project2/sql/sqlBulkLoad.cpp4
-rw-r--r--project2/url/curlHelper.cpp21
-rw-r--r--project2/url/curlHelper.h3
-rw-r--r--project2/url/downloadToFile.cpp4
-rw-r--r--project2/xml/xmlPresenter.cpp4
-rw-r--r--project2/xml/xmlRows.cpp2
-rw-r--r--project2/xml/xpathRows.cpp7
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);
}