void TXFMXPath::evaluateEnvelope(DOMNode *t) { // A special case where the XPath expression is already known if (document == NULL) { throw XSECException(XSECException::XPathError, "Attempt to define XPath Name Space before setInput called"); } DOMElement * e = document->getDocumentElement(); if (e == NULL) { throw XSECException(XSECException::XPathError, "Element node not found in Document"); } // Set the xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" e->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, MAKE_UNICODE_STRING("xmlns:dsig"), DSIGConstants::s_unicodeStrURIDSIG); // Evaluate evaluateExpr(t, XPATH_EXPR_ENVELOPE); // Now we are done, remove the namespace e->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, MAKE_UNICODE_STRING("dsig")); }
bool PromelaDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { PromelaParser parser(expr, 1, PromelaParser::PROMELA_EXPR); // parser.dump(); Data tmp = evaluateExpr(parser.ast); if (tmp.atom.compare("false") == 0) return false; if (tmp.atom.compare("0") == 0) return false; return true; }
void PromelaDataModel::setVariable(void* ast, Data value) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { case PML_VAR_ARRAY: { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; if (INVALID_ASSIGNMENT(name->value)) { ERROR_EXECUTION_THROW("Cannot assign to " + name->value); } int index = dataToInt(evaluateExpr(expr)); if (_variables.compound.find(name->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (!_variables[name->value].hasKey("size")) { ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); } if (strTo<int>(_variables[name->value]["size"].atom) <= index) { ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); } _variables.compound[name->value].compound["value"][index] = value; break; } case PML_NAME: if (INVALID_ASSIGNMENT(node->value)) { ERROR_EXECUTION_THROW("Cannot assign to " + node->value); } _variables.compound[node->value].compound["value"] = value; break; default: break; } // std::cout << Data::toJSON(_variables) << std::endl; }
void PromelaDataModel::evaluateStmnt(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { case PML_ASGN: { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; setVariable(name, evaluateExpr(expr)); break; } case PML_STMNT: { while(opIter != node->operands.end()) { evaluateStmnt(*opIter++); } break; } default: ERROR_EXECUTION_THROW("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); } }
Data PromelaDataModel::getVariable(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; // node->dump(); std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch(node->type) { case PML_NAME: if (_variables.compound.find(node->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + node->value + " was declared"); } // if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) { // ERROR_EXECUTION_THROW("Type error: Variable " + node->value + " is an array"); // } return _variables[node->value]["value"]; case PML_VAR_ARRAY: { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; int index = dataToInt(evaluateExpr(expr)); if (_variables.compound.find(name->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (!_variables[name->value].hasKey("size")) { ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); } if (strTo<int>(_variables[name->value]["size"].atom) <= index) { ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); } return _variables.compound[name->value].compound["value"][index]; } case PML_CMPND: { // node->dump(); // std::cout << Data::toJSON(_variables["_event"]); std::stringstream idPath; PromelaParserNode* name = *opIter++; // special case for _x variables if (name->value.compare("_x") == 0) { PromelaParserNode* what = *opIter++; if (what->type == PML_VAR_ARRAY) { if (what->operands.size() == 2) { std::string arrName = what->operands.front()->value; std::string index = what->operands.back()->value; if (what->operands.back()->type == PML_STRING) { index = index.substr(1, index.size() - 2); // remove quotes } if (arrName.compare("states") == 0) { return Data(_interpreter->isInState(index)); } } } ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (_variables.compound.find(name->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } Data currData = _variables.compound[name->value]["value"]; idPath << name->value; while(opIter != node->operands.end()) { std::string key = (*opIter)->value; idPath << "." << key; if (currData.compound.find(key) == currData.compound.end()) { ERROR_EXECUTION_THROW("No variable " + idPath.str() + " was declared"); } Data tmp = currData.compound[key]; currData = tmp; opIter++; } return currData; } default: ERROR_EXECUTION_THROW("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } return 0; }
Data PromelaDataModel::evaluateExpr(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { case PML_CONST: if (iequals(node->value, "false")) return Data(false); if (iequals(node->value, "true")) return Data(true); return strTo<int>(node->value); case PML_NAME: case PML_VAR_ARRAY: case PML_CMPND: return getVariable(node); case PML_STRING: { std::string stripped = node->value.substr(1, node->value.size() - 2); return Data(stripped, Data::VERBATIM); } case PML_PLUS: return dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++)); case PML_MINUS: return dataToInt(evaluateExpr(*opIter++)) - dataToInt(evaluateExpr(*opIter++)); case PML_DIVIDE: return dataToInt(evaluateExpr(*opIter++)) / dataToInt(evaluateExpr(*opIter++)); case PML_MODULO: return dataToInt(evaluateExpr(*opIter++)) % dataToInt(evaluateExpr(*opIter++)); case PML_EQ: { PromelaParserNode* lhs = *opIter++; PromelaParserNode* rhs = *opIter++; Data left = evaluateExpr(lhs); Data right = evaluateExpr(rhs); if (left == right) // overloaded operator== return Data(true); // literal strings or strings in variables if ((lhs->type == PML_STRING || rhs->type == PML_STRING) || (left.type == Data::VERBATIM && right.type == Data::VERBATIM)) { return (left.atom.compare(right.atom) == 0 ? Data(true) : Data(false)); } return dataToInt(left) == dataToInt(right); } case PML_NEG: return !dataToBool(evaluateExpr(*opIter++)); case PML_LT: return dataToInt(evaluateExpr(*opIter++)) < dataToInt(evaluateExpr(*opIter++)); case PML_LE: return dataToInt(evaluateExpr(*opIter++)) <= dataToInt(evaluateExpr(*opIter++)); case PML_GT: return dataToInt(evaluateExpr(*opIter++)) > dataToInt(evaluateExpr(*opIter++)); case PML_GE: return dataToInt(evaluateExpr(*opIter++)) >= dataToInt(evaluateExpr(*opIter++)); case PML_TIMES: return dataToInt(evaluateExpr(*opIter++)) * dataToInt(evaluateExpr(*opIter++)); case PML_LSHIFT: return dataToInt(evaluateExpr(*opIter++)) << dataToInt(evaluateExpr(*opIter++)); case PML_RSHIFT: return dataToInt(evaluateExpr(*opIter++)) >> dataToInt(evaluateExpr(*opIter++)); case PML_AND: case PML_OR: { PromelaParserNode* lhs = *opIter++; PromelaParserNode* rhs = *opIter++; std::cout << "-----" << std::endl; lhs->dump(); rhs->dump(); Data left = evaluateExpr(lhs); Data right = evaluateExpr(rhs); bool truthLeft = dataToBool(left); bool truthRight = dataToBool(right); if (node->type == PML_AND) { return truthLeft && truthRight; } else { return truthLeft || truthRight; } } default: ERROR_EXECUTION_THROW("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } return 0; }
void PromelaDataModel::evaluateDecl(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; if (false) { } else if (node->type == PML_DECL) { std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); PromelaParserNode* vis = *opIter++; PromelaParserNode* type = *opIter++; PromelaParserNode* varlist = *opIter++; for (std::list<PromelaParserNode*>::iterator nameIter = varlist->operands.begin(); nameIter != varlist->operands.end(); nameIter++) { Data variable; variable.compound["vis"] = Data(vis->value, Data::VERBATIM); variable.compound["type"] = Data(type->value, Data::VERBATIM); if (false) { } else if ((*nameIter)->type == PML_NAME) { // plain variables without initial assignment if (type->value == "mtype") { variable.compound["value"] = Data(_lastMType++, Data::INTERPRETED); } else { variable.compound["value"] = Data(0, Data::INTERPRETED); } _variables.compound[(*nameIter)->value] = variable; } else if ((*nameIter)->type == PML_ASGN) { // initially assigned variables std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; PromelaParserNode* expr = *opIterAsgn++; variable.compound["value"] = evaluateExpr(expr); assert(opIterAsgn == (*nameIter)->operands.end()); _variables.compound[name->value] = variable; } else if ((*nameIter)->type == PML_VAR_ARRAY) { // variable arrays std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; int size = dataToInt(evaluateExpr(*opIterAsgn++)); variable.compound["size"] = size; for (int i = 0; i < size; i++) { variable.compound["value"].array.push_back(Data(0, Data::INTERPRETED)); } assert(opIterAsgn == (*nameIter)->operands.end()); _variables.compound[name->value] = variable; } else { ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc((*nameIter)->type) + " not implemented"); } } assert(opIter == node->operands.end()); } else if (node->type == PML_DECLLIST) { for (std::list<PromelaParserNode*>::iterator declIter = node->operands.begin(); declIter != node->operands.end(); declIter++) { evaluateDecl(*declIter); } } else { ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc(node->type) + " not implemented"); } }
Data PromelaDataModel::evaluateExpr(const std::string& expr) { PromelaParser parser(expr, 1, PromelaParser::PROMELA_EXPR); return evaluateExpr(parser.ast); }
std::string PromelaDataModel::evalAsString(const std::string& expr) { PromelaParser parser(expr); return evaluateExpr(parser.ast); }
Data PromelaDataModel::getStringAsData(const std::string& content) { return evaluateExpr(content); }