summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-07-03 11:31:35 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-07-03 11:31:35 (GMT)
commit67f8e8b4106eb20ce0bc01fd840b0d8e4319cb36 (patch)
tree42ba94ef35bf70d74ebb8dcc03e01752874a6540
parentb542369263782dc8b85893e218119ed070efa7b3 (diff)
downloaduscxml-67f8e8b4106eb20ce0bc01fd840b0d8e4319cb36.zip
uscxml-67f8e8b4106eb20ce0bc01fd840b0d8e4319cb36.tar.gz
uscxml-67f8e8b4106eb20ce0bc01fd840b0d8e4319cb36.tar.bz2
Introduced isLocation for datamodels to check for valid namelist entries
-rw-r--r--src/bindings/swig/wrapped/WrappedDataModel.h4
-rw-r--r--src/uscxml/Interpreter.cpp20
-rw-r--r--src/uscxml/plugins/DataModel.h5
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp13
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h1
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp20
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h1
-rw-r--r--src/uscxml/plugins/datamodel/null/NULLDataModel.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/null/NULLDataModel.h1
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h1
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/promela/PromelaDataModel.h1
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.h1
-rw-r--r--test/w3c/ecma/test553.scxml4
-rw-r--r--test/w3c/ecma/test554.scxml2
17 files changed, 80 insertions, 10 deletions
diff --git a/src/bindings/swig/wrapped/WrappedDataModel.h b/src/bindings/swig/wrapped/WrappedDataModel.h
index e1b29af..481f0ea 100644
--- a/src/bindings/swig/wrapped/WrappedDataModel.h
+++ b/src/bindings/swig/wrapped/WrappedDataModel.h
@@ -99,6 +99,10 @@ public:
return false;
}
+ virtual bool isLocation(const std::string& expr) {
+ return true;
+ }
+
virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
const Arabica::DOM::Node<std::string>& node,
const std::string& content) {
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 5b0db2d..7ae34f2 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -585,8 +585,8 @@ void InterpreterImpl::run(void* instance) {
}
} catch (Event e) {
LOG(ERROR) << e;
- } catch(boost::bad_lexical_cast e) {
- LOG(ERROR) << "InterpreterImpl::run catched exception: " << e.what();
+ } catch(std::exception e) {
+ LOG(ERROR) << "InterpreterImpl::run catched an exception: " << e.what() << std::endl << "Unclean shutdown";
} catch (...) {
LOG(ERROR) << "InterpreterImpl::run catched unknown exception";
}
@@ -1164,9 +1164,10 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) {
if (HAS_ATTR(element, "namelist")) {
std::list<std::string> names = tokenizeIdRefs(ATTR(element, "namelist"));
for (std::list<std::string>::const_iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) {
- if (!_dataModel.isDeclared(*nameIter)) {
- LOG(ERROR) << "Error in send element " << DOMUtils::xPathForNode(element) << " namelist:" << std::endl << "'" << *nameIter << "' is not declared" << std::endl;
+ if (!_dataModel.isLocation(*nameIter)) {
+ LOG(ERROR) << "Error in send element " << DOMUtils::xPathForNode(element) << " namelist:" << std::endl << "'" << *nameIter << "' is not a location expression" << std::endl;
ERROR_EXECUTION2(err, "Location expression '" + *nameIter + "' in namelist is invalid", element);
+ receiveInternal(err);
return;
}
Data namelistValue = _dataModel.getStringAsData(*nameIter);
@@ -1200,6 +1201,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) {
} catch (Event e) {
e.name = "error.execution";
receiveInternal(e);
+ return;
}
// set as content if it's only an atom
if (sendReq.data.atom.length() > 0) {
@@ -1311,7 +1313,15 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) {
if (HAS_ATTR(element, "namelist")) {
std::list<std::string> names = tokenizeIdRefs(ATTR(element, "namelist"));
for (std::list<std::string>::const_iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) {
- invokeReq.namelist[*nameIter] = _dataModel.evalAsString(*nameIter);
+ if (!_dataModel.isLocation(*nameIter)) {
+ LOG(ERROR) << "Error in send element " << DOMUtils::xPathForNode(element) << " namelist:" << std::endl << "'" << *nameIter << "' is not a location expression" << std::endl;
+ ERROR_EXECUTION2(err, "Location expression '" + *nameIter + "' in namelist is invalid", element);
+ receiveInternal(err);
+ return;
+ }
+ Data namelistValue = _dataModel.getStringAsData(*nameIter);
+ invokeReq.namelist[*nameIter] = namelistValue;
+ invokeReq.data.compound[*nameIter] = namelistValue;
}
}
diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h
index f142a60..1a4deba 100644
--- a/src/uscxml/plugins/DataModel.h
+++ b/src/uscxml/plugins/DataModel.h
@@ -41,6 +41,7 @@ public:
virtual std::list<std::string> getNames() = 0;
virtual bool validate(const std::string& location, const std::string& schema) = 0;
+ virtual bool isLocation(const std::string& expr) = 0;
virtual void setEvent(const Event& event) = 0;
virtual Data getStringAsData(const std::string& content) = 0;
@@ -121,6 +122,10 @@ public:
virtual bool validate(const std::string& location, const std::string& schema) {
return _impl->validate(location, schema);
}
+ virtual bool isLocation(const std::string& expr) {
+ return _impl->isLocation(expr);
+ }
+
virtual void setEvent(const Event& event) {
return _impl->setEvent(event);
}
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
index 6dc8c26..73a3744 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
@@ -482,6 +482,19 @@ void JSCDataModel::setForeach(const std::string& item,
}
}
+bool JSCDataModel::isLocation(const std::string& expr) {
+ JSStringRef scriptJS = JSStringCreateWithUTF8CString((expr + "++").c_str());
+ JSValueRef exception = NULL;
+ bool valid = JSCheckScriptSyntax(_ctx, scriptJS, NULL, 0, &exception);
+ JSStringRelease(scriptJS);
+
+ if (exception || !valid) {
+ return false;
+ }
+ return true;
+}
+
+
bool JSCDataModel::isDeclared(const std::string& expr) {
JSStringRef scriptJS = JSStringCreateWithUTF8CString(expr.c_str());
JSValueRef exception = NULL;
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h
index 82882f0..fea2234 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h
@@ -49,6 +49,7 @@ public:
}
virtual bool validate(const std::string& location, const std::string& schema);
+ virtual bool isLocation(const std::string& expr);
virtual void setEvent(const Event& event);
virtual Data getStringAsData(const std::string& content);
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 8b222f7..a995ec2 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -457,6 +457,22 @@ bool V8DataModel::validate(const std::string& location, const std::string& schem
return true;
}
+bool V8DataModel::isLocation(const std::string& expr) {
+ v8::Locker locker;
+ v8::HandleScope handleScope;
+ v8::TryCatch tryCatch;
+ v8::Context::Scope contextScope(_contexts.back());
+
+ v8::Handle<v8::String> source = v8::String::New((expr + "++").c_str());
+ v8::Handle<v8::Script> script = v8::Script::Compile(source);
+
+ if (script.IsEmpty() || tryCatch.HasCaught()) {
+ return false;
+ }
+
+ return true;
+}
+
uint32_t V8DataModel::getLength(const std::string& expr) {
v8::Locker locker;
v8::HandleScope handleScope;
@@ -468,7 +484,7 @@ uint32_t V8DataModel::getLength(const std::string& expr) {
Event exceptionEvent;
exceptionEvent.name = "error.execution";
- exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);
+ exceptionEvent.data.compound["cause"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);
throw(exceptionEvent);
}
@@ -720,7 +736,7 @@ void V8DataModel::throwExceptionEvent(const v8::TryCatch& tryCatch) {
exceptionEvent.eventType = Event::PLATFORM;
std::string exceptionString(*v8::String::AsciiValue(tryCatch.Exception()));
- exceptionEvent.data.compound["exception"] = Data(exceptionString, Data::VERBATIM);;
+ exceptionEvent.data.compound["cause"] = Data(exceptionString, Data::VERBATIM);;
v8::Handle<v8::Message> message = tryCatch.Message();
if (!message.IsEmpty()) {
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
index 5bfca93..6df1951 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
@@ -53,6 +53,7 @@ public:
virtual void setEvent(const Event& event);
virtual bool validate(const std::string& location, const std::string& schema);
+ virtual bool isLocation(const std::string& expr);
virtual uint32_t getLength(const std::string& expr);
virtual void setForeach(const std::string& item,
diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
index 45d7a5c..073657a 100644
--- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
@@ -76,6 +76,10 @@ bool NULLDataModel::validate(const std::string& location, const std::string& sch
return true;
}
+bool NULLDataModel::isLocation(const std::string& expr) {
+ return true;
+}
+
uint32_t NULLDataModel::getLength(const std::string& expr) {
return 0;
}
diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.h b/src/uscxml/plugins/datamodel/null/NULLDataModel.h
index 162ffdb..f9609c4 100644
--- a/src/uscxml/plugins/datamodel/null/NULLDataModel.h
+++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.h
@@ -50,6 +50,7 @@ public:
virtual void setEvent(const Event& event);
virtual bool validate(const std::string& location, const std::string& schema);
+ virtual bool isLocation(const std::string& expr);
virtual uint32_t getLength(const std::string& expr);
virtual void setForeach(const std::string& item,
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
index 8f5e588..924e14a 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
@@ -607,6 +607,10 @@ bool SWIDataModel::validate(const std::string& location, const std::string& sche
return true;
}
+bool SWIDataModel::isLocation(const std::string& expr) {
+ return true;
+}
+
uint32_t SWIDataModel::getLength(const std::string& expr) {
SWIEngineLock engineLock;
try {
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
index f022811..a673a40 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
@@ -68,6 +68,7 @@ public:
virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor);
virtual bool validate(const std::string& location, const std::string& schema);
+ virtual bool isLocation(const std::string& expr);
virtual uint32_t getLength(const std::string& expr);
virtual void setForeach(const std::string& item,
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
index 4300512..6d34677 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp
@@ -98,6 +98,10 @@ bool PromelaDataModel::validate(const std::string& location, const std::string&
return true;
}
+bool PromelaDataModel::isLocation(const std::string& expr) {
+ return true;
+}
+
uint32_t PromelaDataModel::getLength(const std::string& expr) {
if (!isDeclared(expr)) {
ERROR_EXECUTION_THROW("Variable '" + expr + "' was not declared");
diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h
index cbbf570..ca6b19d 100644
--- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h
+++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h
@@ -49,6 +49,7 @@ public:
virtual void registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor);
virtual bool validate(const std::string& location, const std::string& schema);
+ virtual bool isLocation(const std::string& expr);
virtual uint32_t getLength(const std::string& expr);
virtual void setForeach(const std::string& item,
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
index 3b28547..c38842b 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
@@ -285,6 +285,10 @@ bool XPathDataModel::validate(const std::string& location, const std::string& sc
return true;
}
+bool XPathDataModel::isLocation(const std::string& expr) {
+ return true;
+}
+
uint32_t XPathDataModel::getLength(const std::string& expr) {
// std::cout << _datamodel << std::endl;
XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc);
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
index d18d05a..09d63fa 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
@@ -95,6 +95,7 @@ public:
virtual void setEvent(const Event& event);
virtual bool validate(const std::string& location, const std::string& schema);
+ virtual bool isLocation(const std::string& expr);
virtual uint32_t getLength(const std::string& expr);
virtual void setForeach(const std::string& item,
diff --git a/test/w3c/ecma/test553.scxml b/test/w3c/ecma/test553.scxml
index 0df3c3e..3dd0aeb 100644
--- a/test/w3c/ecma/test553.scxml
+++ b/test/w3c/ecma/test553.scxml
@@ -5,9 +5,9 @@ of <send>'s args causes an error.. --><scxml xmlns="http://www.w3.org/2005/07/s
<state id="s0">
<onentry>
<!-- timeout event -->
- <send event="timeout" delayexpr="'50ms'"/>
+ <send event="timeout" delayexpr="'500ms'"/>
<!-- generate an invalid namelist -->
- <send event="event1" namelist="&#34;foo&#34;"/>
+ <send event="event1" namelist="&#34;foo"/>
</onentry>
<!-- if we get the timeout before event1, we assume that event1 hasn't been sent
diff --git a/test/w3c/ecma/test554.scxml b/test/w3c/ecma/test554.scxml
index 764241e..b2fa50e 100644
--- a/test/w3c/ecma/test554.scxml
+++ b/test/w3c/ecma/test554.scxml
@@ -9,7 +9,7 @@ before the timer goes off. --><scxml xmlns="http://www.w3.org/2005/07/scxml" xm
</onentry>
<!-- reference an invalid namelist -->
- <invoke type="http://www.w3.org/TR/scxml/" namelist="&#34;foo&#34;">
+ <invoke type="http://www.w3.org/TR/scxml/" namelist="&#34;foo">
<content>
<scxml initial="subFinal" version="1.0" datamodel="ecmascript">
<final id="subFinal"/>