bugfix for bad {SCENARIODIR} replacement

Done by softcoder in branch ce-gui, manually merged by me :)
https://forum.megaglest.org/index.php?topic=9553.0
This commit is contained in:
titiger 2014-09-24 01:16:28 +02:00
parent 913f586dbc
commit 1f5b571c9d
7 changed files with 90 additions and 40 deletions

View File

@ -78,6 +78,7 @@ Checksum Scenario::load(const string &path) {
//parse xml
XmlTree xmlTree;
xmlTree.setSkipUpdatePathClimbingParts(true);
xmlTree.load(path,Properties::getTagReplacementValues());
const XmlNode *scenarioNode= xmlTree.getRootNode();
const XmlNode *scriptsNode= scenarioNode->getChild("scripts");

View File

@ -227,7 +227,7 @@ bool EndsWith(const string &str, const string& key);
void endPathWithSlash(string &path, bool requireOSSlash=false);
void trimPathWithStartingSlash(string &path);
void updatePathClimbingParts(string &path);
void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck=true);
string formatPath(string path);
string replaceAllHTMLEntities(string& context);

View File

@ -100,10 +100,10 @@ public:
bool hasString(const string &key) const;
static bool applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues=NULL);
static bool applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues=NULL, bool skipUpdatePathClimbingParts=false);
static std::map<string,string> getTagReplacementValues(std::map<string,string> *mapExtraTagReplacementValues=NULL);
static bool isValuePathVariable(const string &value);
static void updateValuePathVariable(string &value);
static void updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts=false);
string getpath() const { return path;}

View File

@ -124,7 +124,7 @@ public:
static bool isInitialized();
void cleanup();
XmlNode *load(const string &path, const std::map<string,string> &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false);
XmlNode *load(const string &path, const std::map<string,string> &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false,bool skipUpdatePathClimbingParts=false);
void save(const string &path, const XmlNode *node);
};
@ -138,6 +138,7 @@ private:
string loadPath;
xml_engine_parser_type engine_type;
bool skipStackCheck;
bool skipUpdatePathClimbingParts;
private:
XmlTree(XmlTree&);
void operator =(XmlTree&);
@ -147,6 +148,7 @@ public:
XmlTree(xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE);
~XmlTree();
void setSkipUpdatePathClimbingParts(bool value);
void init(const string &name);
void load(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false);
void save(const string &path);
@ -182,7 +184,7 @@ public:
#endif
XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues);
XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues,bool skipUpdatePathClimbingParts=false);
XmlNode(const string &name);
~XmlNode();

View File

@ -561,7 +561,7 @@ void trimPathWithStartingSlash(string &path) {
}
}
void updatePathClimbingParts(string &path) {
void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck) {
// Update paths with /./
string::size_type pos = path.find("/./");
if(pos != string::npos && pos != 0) {
@ -569,9 +569,11 @@ void updatePathClimbingParts(string &path) {
path.erase(pos,2);
//pos--;
//printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
pos = path.find("/./");
if(pos != string::npos && pos != 0) {
updatePathClimbingParts(path);
updatePathClimbingParts(path, processPreviousDirTokenCheck);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
@ -581,39 +583,65 @@ void updatePathClimbingParts(string &path) {
string orig = path;
path.erase(pos,2);
//pos--;
//printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
pos = path.find("\\.\\");
if(pos != string::npos && pos != 0) {
updatePathClimbingParts(path);
updatePathClimbingParts(path, processPreviousDirTokenCheck);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
}
// Update paths with ..
pos = path.find("..");
if(pos != string::npos && pos != 0) {
string orig = path;
path.erase(pos,2);
pos--;
if(path[pos] == '/' || path[pos] == '\\') {
path.erase(pos,1);
}
for(int x = (int)pos; x >= 0; --x) {
//printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
if((path[x] == '/' || path[x] == '\\') && x != (int)pos) {
path.erase(x,pos-x);
break;
}
}
if(processPreviousDirTokenCheck) {
pos = path.find("..");
if(pos != string::npos && pos != 0) {
updatePathClimbingParts(path);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
string orig = path;
if(path[pos-1] != ' ' || (path.length() > 2 && path[pos+2] != ' ')) {
path.erase(pos,2);
//printf("#3 [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,orig.c_str(),path.c_str());
pos--;
//pos = pos -1;
//printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3b [%d]\n",(int)pos);
if(path[pos] == '/' || path[pos] == '\\') {
path.erase(pos,1);
//printf("#4 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
}
for(int x = (int)pos; x >= 0; --x) {
//printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
if((path[x] == '/' || path[x] == '\\') && x != (int)pos) {
string origLoop = path;
path.erase(x,(int)pos-x);
//printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str());
break;
}
}
pos = path.find("..");
}
else {
//printf("#6a [%d]\n",(int)pos);
//pos = path.find("..",pos+1);
pos = string::npos;
//printf("#6b [%d]\n",(int)pos);
}
if(pos != string::npos && pos != 0) {
updatePathClimbingParts(path,processPreviousDirTokenCheck);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
}
}
/*

View File

@ -285,13 +285,15 @@ bool Properties::isValuePathVariable(const string &value) {
}
return false;
}
void Properties::updateValuePathVariable(string &value) {
void Properties::updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts) {
replaceAll(value,"//","/");
replaceAll(value,"\\\\","\\");
updatePathClimbingParts(value);
if(skipUpdatePathClimbingParts == false) {
updatePathClimbingParts(value);
}
}
bool Properties::applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues) {
bool Properties::applyTagsToValue(string &value, const std::map<string,string> *mapTagReplacementValues,bool skipUpdatePathClimbingParts) {
string originalValue = value;
bool valueRequiresPathUpdate = Properties::isValuePathVariable(value);
//if(originalValue.find("$APPLICATIONDATAPATH") != string::npos) {
@ -389,7 +391,7 @@ bool Properties::applyTagsToValue(string &value, const std::map<string,string> *
//}
if(valueRequiresPathUpdate == true) {
Properties::updateValuePathVariable(value);
Properties::updateValuePathVariable(value, skipUpdatePathClimbingParts);
}
return (originalValue != value);
}

View File

@ -339,7 +339,8 @@ XmlIoRapid::~XmlIoRapid() {
cleanup();
}
XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &mapTagReplacementValues,bool noValidation,bool skipStackTrace) {
XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &mapTagReplacementValues,
bool noValidation,bool skipStackTrace,bool skipUpdatePathClimbingParts) {
bool showPerfStats = SystemFlags::VERBOSE_MODE_ENABLED;
Chrono chrono;
chrono.start();
@ -388,7 +389,7 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &map
// Load data and add terminating 0
vector<char> buffer;
buffer.resize((unsigned int)file_size + 1);
buffer.resize((unsigned int)file_size + 100);
xmlFile.read(&buffer.front(), static_cast<streamsize>(file_size));
buffer[(unsigned int)file_size] = 0;
@ -405,7 +406,7 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map<string,string> &map
if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
rootNode= new XmlNode(doc.first_node(),mapTagReplacementValues);
rootNode= new XmlNode(doc.first_node(),mapTagReplacementValues, skipUpdatePathClimbingParts);
if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
@ -522,6 +523,7 @@ XmlTree::XmlTree(xml_engine_parser_type engine_type) {
this->engine_type = engine_type;
this->skipStackCheck = false;
this->skipUpdatePathClimbingParts = false;
}
void XmlTree::init(const string &name){
@ -533,6 +535,10 @@ typedef std::vector<XmlTree*> LoadStack;
//static LoadStack loadStack;
static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName");
void XmlTree::setSkipUpdatePathClimbingParts(bool value) {
this->skipUpdatePathClimbingParts = value;
}
void XmlTree::load(const string &path, const std::map<string,string> &mapTagReplacementValues, bool noValidation,bool skipStackCheck,bool skipStackTrace) {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] skipStackCheck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),skipStackCheck);
@ -565,7 +571,7 @@ void XmlTree::load(const string &path, const std::map<string,string> &mapTagRepl
else
#endif
{
this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace);
this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace, this->skipUpdatePathClimbingParts);
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str());
@ -661,7 +667,8 @@ XmlNode::XmlNode(DOMNode *node, const std::map<string,string> &mapTagReplacement
#endif
XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues) : superNode(NULL) {
XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacementValues,
bool skipUpdatePathClimbingParts) : superNode(NULL) {
if(node == NULL || node->name() == NULL) {
throw megaglest_runtime_error("XML structure seems to be corrupt!");
}
@ -682,7 +689,7 @@ XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacem
for(xml_node<> *currentNode = node->first_node();
currentNode; currentNode = currentNode->next_sibling()) {
if(currentNode != NULL && currentNode->type() == node_element) {
XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues);
XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues, skipUpdatePathClimbingParts);
children.push_back(xmlNode);
}
}
@ -696,8 +703,18 @@ XmlNode::XmlNode(xml_node<> *node, const std::map<string,string> &mapTagReplacem
//get value
if(node->type() == node_element && children.size() == 0) {
text = node->value();
Properties::applyTagsToValue(this->text,&mapTagReplacementValues);
string xmlText = node->value();
bool debugReplace = false;
// if(xmlText.find("{SCENARIOPATH}") != string::npos) {
// printf("\n----------------------\n** XML!! WILL REPLACE [%s]\n",xmlText.c_str());
// debugReplace = true;
// }
Properties::applyTagsToValue(xmlText,&mapTagReplacementValues, skipUpdatePathClimbingParts);
if(debugReplace) {
printf("\n\n** XML!! REPLACED WITH [%s]\n===================\n",xmlText.c_str());
}
text = xmlText;
}
}