summaryrefslogtreecommitdiffstats
path: root/src/uscxml/util
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2016-06-13 08:52:55 (GMT)
committerStefan Radomski <github@mintwerk.de>2016-06-13 08:52:55 (GMT)
commit053e9bc973fbe88fc41a34064ffadc0deabac58d (patch)
tree6aeee286577159ffcb612d41972a9d18ab685c6d /src/uscxml/util
parent6e13c7b6e0888323223afd5d2e36e86243df57af (diff)
downloaduscxml-053e9bc973fbe88fc41a34064ffadc0deabac58d.zip
uscxml-053e9bc973fbe88fc41a34064ffadc0deabac58d.tar.gz
uscxml-053e9bc973fbe88fc41a34064ffadc0deabac58d.tar.bz2
Fixed dozens of memory leaks
Diffstat (limited to 'src/uscxml/util')
-rw-r--r--src/uscxml/util/DOM.cpp45
-rw-r--r--src/uscxml/util/DOM.h96
-rw-r--r--src/uscxml/util/Predicates.cpp51
-rw-r--r--src/uscxml/util/URL.cpp20
-rw-r--r--src/uscxml/util/URL.h7
5 files changed, 149 insertions, 70 deletions
diff --git a/src/uscxml/util/DOM.cpp b/src/uscxml/util/DOM.cpp
index ecf0960..7793fb5 100644
--- a/src/uscxml/util/DOM.cpp
+++ b/src/uscxml/util/DOM.cpp
@@ -52,7 +52,7 @@ std::ostream& operator<< (std::ostream& os, const DOMNode& node) {
}
std::ostream& operator<< (std::ostream& os, const X& xmlString) {
- os << xmlString._localForm;
+ os << xmlString.str();
return os;
}
@@ -236,20 +236,13 @@ void DOMUtils::inPostFixOrder(const std::set<std::string>& elements,
if (root == NULL)
return;
- DOMNodeList* children = root->getChildNodes();
- for (size_t i = 0; i < children->getLength(); i++) {
- if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
- const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i));
+ for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
if (!includeEmbeddedDoc && LOCALNAME(childElem) == "scxml")
continue;
inPostFixOrder(elements, childElem, includeEmbeddedDoc, nodes);
}
- for (size_t i = 0; i < children->getLength(); i++) {
- if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
- const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i));
+ for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml")
continue;
@@ -278,14 +271,14 @@ void DOMUtils::inDocumentOrder(const std::set<std::string>& elements,
nodes.push_back((DOMElement*)root);
}
- DOMNodeList* children = root->getChildNodes();
- for (size_t i = 0; i < children->getLength(); i++) {
- if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
- const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i));
- if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml")
- continue;
- inDocumentOrder(elements, childElem, includeEmbeddedDoc, nodes);
+ /// @todo: item from getChildNodes is O(N)!
+ DOMElement* child = root->getFirstElementChild();
+ while(child) {
+ if (includeEmbeddedDoc || TAGNAME(child) != XML_PREFIX(root).str() + "scxml") {
+ inDocumentOrder(elements, child, includeEmbeddedDoc, nodes);
+ }
+
+ child = child->getNextElementSibling();
}
}
@@ -350,12 +343,7 @@ std::list<DOMElement*> DOMUtils::filterChildElements(const std::string& tagName,
if (!node)
return filteredChildElems;
- DOMNodeList* children = node->getChildNodes();
- for (unsigned int i = 0; i < children->getLength(); i++) {
- if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
- const DOMElement* childElem = dynamic_cast<const DOMElement*>(children->item(i));
-
+ for (auto childElem = node->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
// std::cerr << TAGNAME(childs.item(i)) << std::endl;
if(iequals(TAGNAME(childElem), tagName)) {
filteredChildElems.push_back((DOMElement*)childElem);
@@ -391,12 +379,11 @@ std::list<DOMNode*> DOMUtils::filterChildType(const DOMNode::NodeType type,
if (!node)
return filteredChildTypes;
- DOMNodeList* children = node->getChildNodes();
- for (unsigned int i = 0; i < children->getLength(); i++) {
- if (children->item(i)->getNodeType() == type)
- filteredChildTypes.push_back(children->item(i));
+ for (auto child = node->getFirstChild(); child; child = child->getNextSibling()) {
+ if (child->getNodeType() == type)
+ filteredChildTypes.push_back(child);
if (recurse) {
- std::list<DOMNode*> nested = filterChildType(type, children->item(i), recurse);
+ std::list<DOMNode*> nested = filterChildType(type, child, recurse);
filteredChildTypes.merge(nested);
}
diff --git a/src/uscxml/util/DOM.h b/src/uscxml/util/DOM.h
index f259ea0..3ab27a3 100644
--- a/src/uscxml/util/DOM.h
+++ b/src/uscxml/util/DOM.h
@@ -117,17 +117,18 @@ protected:
// create a prefix from a given element - useful for copying namespace information
#define XML_PREFIX(element) X(element->getPrefix() ? X(element->getPrefix()).str() + ":" : "")
+#if 1
class USCXML_API X {
public :
X(X const &other) {
_localForm = other._localForm;
- _otherForm = XERCESC_NS::XMLString::replicate(other._otherForm);
+ _unicodeForm = XERCESC_NS::XMLString::replicate(other._unicodeForm);
_deallocOther = true;
}
void operator=(X const &other) { // did we maybe leak before?
_localForm = other._localForm;
- _otherForm = XERCESC_NS::XMLString::replicate(other._otherForm);
+ _unicodeForm = XERCESC_NS::XMLString::replicate(other._unicodeForm);
_deallocOther = true;
}
@@ -138,39 +139,39 @@ public :
_localForm = std::string(tmp);
XERCESC_NS::XMLString::release(&tmp);
}
- _otherForm = NULL;
+ _unicodeForm = NULL;
_deallocOther = false;
}
X(const std::string& fromTranscode) {
// Call the private transcoding method
_localForm = fromTranscode;
- _otherForm = XERCESC_NS::XMLString::transcode(fromTranscode.c_str());
+ _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode.c_str());
_deallocOther = true;
}
X(const char* const fromTranscode) {
// Call the private transcoding method
_localForm = fromTranscode;
- _otherForm = XERCESC_NS::XMLString::transcode(fromTranscode);
+ _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode);
_deallocOther = true;
}
X(char* fromTranscode) {
// Call the private transcoding method
_localForm = fromTranscode;
- _otherForm = XERCESC_NS::XMLString::transcode(fromTranscode);
+ _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode);
_deallocOther = true;
}
X() {
- _otherForm = NULL;
+ _unicodeForm = NULL;
_deallocOther = false;
}
~X() {
if (_deallocOther)
- XERCESC_NS::XMLString::release(&_otherForm);
+ XERCESC_NS::XMLString::release(&_unicodeForm);
}
const std::string& str() const {
@@ -178,8 +179,8 @@ public :
}
operator const XMLCh* () {
- assert(_otherForm != NULL); // constructor with XMLCh
- return _otherForm;
+ assert(_unicodeForm != NULL); // constructor with XMLCh
+ return _unicodeForm;
}
operator bool () {
@@ -196,9 +197,82 @@ protected:
private:
bool _deallocOther;
std::string _localForm;
- XMLCh* _otherForm;
+ XMLCh* _unicodeForm;
};
+
+#else
+class USCXML_API X {
+public :
+ X() {
+ }
+
+ void operator=(X const &other) {
+ localForm = other.localForm;
+ if (unicodeForm != NULL) {
+ XERCESC_NS::XMLString::release(&unicodeForm);
+ }
+ unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm);
+ }
+
+ X(X const &other) {
+ localForm = other.localForm;
+ unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm);
+ }
+
+ X(const char* const toTranscode) {
+ if (toTranscode != NULL) {
+ localForm = toTranscode;
+ unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode);
+ }
+ }
+
+ X(const XMLCh* toTranscode) {
+ if (toTranscode != NULL) {
+ unicodeForm = XERCESC_NS::XMLString::replicate(toTranscode);
+ localForm = XERCESC_NS::XMLString::transcode(toTranscode);
+ }
+ }
+
+ X(const std::string& toTranscode) {
+ localForm = toTranscode;
+ unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode.c_str());
+ }
+
+ ~X() {
+ if (unicodeForm != NULL) {
+ XERCESC_NS::XMLString::release(&unicodeForm);
+ }
+ }
+
+ operator XMLCh* () const {
+ return unicodeForm;
+ }
+
+ operator const std::string& () {
+ return localForm;
+ }
+
+ const std::string& str() const {
+ return localForm;
+ }
+
+ const XMLCh* unicode() const {
+ return unicodeForm;
+ }
+
+
+protected:
+ friend USCXML_API std::ostream& operator<< (std::ostream& os, const X& data);
+
+private:
+ XMLCh* unicodeForm = NULL;
+ std::string localForm;
+
+};
+
+#endif
+
USCXML_API std::ostream& operator<< (std::ostream& os, const X& xmlString);
USCXML_API std::ostream& operator<< (std::ostream& os, const XERCESC_NS::DOMNode& node);
diff --git a/src/uscxml/util/Predicates.cpp b/src/uscxml/util/Predicates.cpp
index 2f46d75..cd41089 100644
--- a/src/uscxml/util/Predicates.cpp
+++ b/src/uscxml/util/Predicates.cpp
@@ -27,11 +27,7 @@ using namespace XERCESC_NS;
std::list<DOMElement*> getChildStates(const DOMElement* state, bool properOnly) {
std::list<DOMElement*> children;
- DOMNodeList* childElems = state->getChildNodes();
- for (size_t i = 0; i < childElems->getLength(); i++) {
- if (childElems->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
- DOMElement* childElem = dynamic_cast<DOMElement*>(childElems->item(i));
+ for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
if (isState(childElem, properOnly)) {
children.push_back(childElem);
}
@@ -74,17 +70,23 @@ DOMElement* getSourceState(const DOMElement* transition) {
#define VERBOSE_FIND_LCCA 0
DOMElement* findLCCA(const std::list<DOMElement*>& states) {
-
+
std::list<DOMElement*> ancestors = getProperAncestors(states.front(), NULL);
DOMElement* ancestor = NULL;
+#if VERBOSE_FIND_LCCA
+ std::cout << "states: " << states.size() << std::endl;
+ std::cout << "front: " << DOMUtils::xPathForNode(states.front()) << std::endl;
+ std::cout << "ancestors: " << ancestors.size() << std::endl;
+#endif
+
for (auto ancIter = ancestors.begin(); ancIter != ancestors.end(); ancIter++) {
if (!isCompound(dynamic_cast<DOMElement*>(*ancIter)))
continue;
for (auto stateIter = states.begin(); stateIter != states.end(); stateIter++) {
#if VERBOSE_FIND_LCCA
- std::cerr << "Checking " << ATTR_CAST(states[j], "id") << " and " << ATTR_CAST(ancestors[i], "id") << std::endl;
+ std::cerr << "Checking " << ATTR_CAST(*stateIter, "id") << " and " << ATTR_CAST(*ancIter, "id") << std::endl;
#endif
if (!DOMUtils::isDescendant(*stateIter, *ancIter))
@@ -97,11 +99,11 @@ NEXT_ANCESTOR:
}
// take uppermost root as ancestor
- if (!ancestor)
+ if (!ancestor && ancestors.size() > 0)
ancestor = ancestors.back();
#if VERBOSE_FIND_LCCA
- std::cerr << " -> " << ATTR_CAST(ancestor, "id") << " " << ancestor.getLocalName() << std::endl;
+ std::cerr << " -> " << ATTR_CAST(ancestor, "id") << " " << ancestor->getLocalName() << std::endl;
#endif
return ancestor;
}
@@ -118,7 +120,9 @@ NEXT_ANCESTOR:
std::list<DOMElement*> getProperAncestors(const DOMElement* s1, const DOMElement* s2) {
std::list<DOMElement*> ancestors;
- if (isState(s1)) {
+ if (isState(s1, false)) {
+ // is it correct to also consider pseudo-states?
+ // gcc bug in findLCCA with test387, test388, test579, test580 otherwise
DOMNode* node = (DOMNode*)s1;
while((node = node->getParentNode())) {
if (node->getNodeType() != DOMNode::ELEMENT_NODE)
@@ -127,9 +131,10 @@ std::list<DOMElement*> getProperAncestors(const DOMElement* s1, const DOMElement
const DOMElement* nodeElem = dynamic_cast<const DOMElement*>(node);
if (!isState(nodeElem))
break;
+
if (!iequals(LOCALNAME(nodeElem), "parallel") &&
- !iequals(LOCALNAME(nodeElem), "state") &&
- !iequals(LOCALNAME(nodeElem), "scxml"))
+ !iequals(LOCALNAME(nodeElem), "state") &&
+ !iequals(LOCALNAME(nodeElem), "scxml"))
break;
if (node == s2)
break;
@@ -143,10 +148,11 @@ std::list<DOMElement*> getExitSet(const DOMElement* transition, const DOMElement
std::list<DOMElement*> statesToExit;
if (HAS_ATTR(transition, "target")) {
DOMElement* domain = getTransitionDomain(transition, root);
- if (!domain)
+ if (domain == NULL)
return statesToExit;
- // std::cout << DOMUtils::xPathForNode(domain) << std::endl;
+// std::cout << "transition: " << DOMUtils::xPathForNode(transition) << std::endl;
+// std::cout << "domain: " << DOMUtils::xPathForNode(domain) << std::endl;
std::set<std::string> elements;
elements.insert(XML_PREFIX(transition).str() + "parallel");
@@ -157,16 +163,20 @@ std::list<DOMElement*> getExitSet(const DOMElement* transition, const DOMElement
if (statesToExit.front() == domain) {
statesToExit.pop_front(); // do not include domain itself
}
+// std::cout << "OK" << std::endl;
+
}
return statesToExit;
}
bool conflicts(const DOMElement* t1, const DOMElement* t2, const DOMElement* root) {
- return (DOMUtils::hasIntersection(getExitSet(t1, root), getExitSet(t2, root)) ||
- (getSourceState(t1) == getSourceState(t2)) ||
+ return (
+ (getSourceState(t1) == getSourceState(t2)) ||
(DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) ||
- (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))));
+ (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) ||
+ (DOMUtils::hasIntersection(getExitSet(t1, root), getExitSet(t2, root)))
+ );
}
bool isState(const DOMElement* state, bool properOnly) {
@@ -280,6 +290,7 @@ DOMElement* getTransitionDomain(const DOMElement* transition, const DOMElement*
BREAK_LOOP:
tStates.push_front(source);
+
return findLCCA(tStates);
}
@@ -359,11 +370,7 @@ std::list<DOMElement*> getInitialStates(const DOMElement* state, const DOMElemen
// first child state
std::list<DOMElement*> initStates;
- DOMNodeList* children = state->getChildNodes();
- for (size_t i = 0; i < children->getLength(); i++) {
- if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
- continue;
- DOMElement* childElem = dynamic_cast<DOMElement*>(children->item(i));
+ for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) {
if (isState(childElem)) {
initStates.push_back(childElem);
return initStates;
diff --git a/src/uscxml/util/URL.cpp b/src/uscxml/util/URL.cpp
index a76c772..2e98fce 100644
--- a/src/uscxml/util/URL.cpp
+++ b/src/uscxml/util/URL.cpp
@@ -118,6 +118,8 @@ URLImpl::URLImpl(const std::string& url) : _orig(url), _handle(NULL), _isDownloa
URLImpl::~URLImpl() {
uriFreeUriMembersA(&_uri);
+ if (_handle != NULL)
+ curl_easy_cleanup(_handle);
}
URL URLImpl::resolve(URLImpl* relative, URLImpl* absolute) {
@@ -590,7 +592,7 @@ void URLFetcher::fetchURL(URL& url) {
char* header = (char*)malloc(paramIter->first.size() + strlen(value) + 3);
sprintf(header,"%s: %s", paramIter->first.c_str(), value);
headers = curl_slist_append(headers, header);
-
+ free(header);
// curl_free(key);
// curl_free(value);
paramIter++;
@@ -598,11 +600,12 @@ void URLFetcher::fetchURL(URL& url) {
// Disable "Expect: 100-continue"
headers = curl_slist_append(headers, "Expect:");
+ instance->_handlesToHeaders[handle] = headers;
- (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK ||
+ (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK ||
LOG(ERROR) << "Cannot headers for " << std::string(url) << ": " << curl_easy_strerror(curlError);
- //curl_slist_free_all(headers);
+// curl_slist_free_all(headers);
} else if (url._impl->_requestType == URLRequestType::GET) {
@@ -629,6 +632,10 @@ void URLFetcher::breakURL(URL& url) {
curl_multi_remove_handle(instance->_multiHandle, handle);
instance->_handlesToURLs.erase(handle);
}
+ if (instance->_handlesToHeaders.find(handle) != instance->_handlesToHeaders.end()) {
+ curl_slist_free_all(instance->_handlesToHeaders[handle]);
+ instance->_handlesToHeaders.erase(handle);
+ }
}
void URLFetcher::start() {
@@ -745,7 +752,6 @@ void URLFetcher::perform() {
LOG(WARNING) << "curl_multi_remove_handle: " << curl_multi_strerror(err);
}
- _handlesToURLs.erase(msg->easy_handle);
break;
default:
_handlesToURLs[msg->easy_handle]._impl->downloadFailed(msg->data.result);
@@ -753,9 +759,13 @@ void URLFetcher::perform() {
if (err != CURLM_OK) {
LOG(WARNING) << "curl_multi_remove_handle: " << curl_multi_strerror(err);
}
+ break;
- _handlesToURLs.erase(msg->easy_handle);
}
+ _handlesToURLs.erase(msg->easy_handle);
+ curl_slist_free_all(_handlesToHeaders[msg->easy_handle]);
+ _handlesToHeaders.erase(msg->easy_handle);
+
} else {
LOG(ERROR) << "Curl reports info on unfinished download?!";
}
diff --git a/src/uscxml/util/URL.h b/src/uscxml/util/URL.h
index 8127892..2b5c9e0 100644
--- a/src/uscxml/util/URL.h
+++ b/src/uscxml/util/URL.h
@@ -165,7 +165,7 @@ protected:
static void prepareException(ErrorEvent& exception, int errorCode, const std::string& origUri, UriParserStateA* parser);
- CURL* _handle;
+ CURL* _handle = NULL;
std::stringstream _rawInContent;
std::stringstream _rawInHeader;
std::map<std::string, std::string> _inHeaders;
@@ -176,8 +176,8 @@ protected:
std::string _statusCode;
std::string _statusMsg;
- bool _isDownloaded;
- bool _hasFailed;
+ bool _isDownloaded = false;
+ bool _hasFailed = false;
std::string _error;
std::condition_variable_any _condVar;
@@ -325,6 +325,7 @@ protected:
bool _isStarted;
std::map<CURL*, URL> _handlesToURLs;
+ std::map<CURL*, curl_slist*> _handlesToHeaders;
CURLM* _multiHandle;
char* _envProxy;
};