diff --git a/source/glest_game/world/scenario.cpp b/source/glest_game/world/scenario.cpp index e08c4f93e..63f19e6ea 100644 --- a/source/glest_game/world/scenario.cpp +++ b/source/glest_game/world/scenario.cpp @@ -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"); diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index 667d4ea84..8218b1cff 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -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); diff --git a/source/shared_lib/include/util/properties.h b/source/shared_lib/include/util/properties.h index 64bf8f819..8aa3b272f 100644 --- a/source/shared_lib/include/util/properties.h +++ b/source/shared_lib/include/util/properties.h @@ -100,10 +100,10 @@ public: bool hasString(const string &key) const; - static bool applyTagsToValue(string &value, const std::map *mapTagReplacementValues=NULL); + static bool applyTagsToValue(string &value, const std::map *mapTagReplacementValues=NULL, bool skipUpdatePathClimbingParts=false); static std::map getTagReplacementValues(std::map *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;} diff --git a/source/shared_lib/include/xml/xml_parser.h b/source/shared_lib/include/xml/xml_parser.h index 3057cb071..d7fd4e832 100644 --- a/source/shared_lib/include/xml/xml_parser.h +++ b/source/shared_lib/include/xml/xml_parser.h @@ -124,7 +124,7 @@ public: static bool isInitialized(); void cleanup(); - XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false); + XmlNode *load(const string &path, const std::map &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 &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 &mapTagReplacementValues); + XmlNode(xml_node<> *node, const std::map &mapTagReplacementValues,bool skipUpdatePathClimbingParts=false); XmlNode(const string &name); ~XmlNode(); diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index 7b5eda7a0..dbc6428e9 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -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()); + } } /* diff --git a/source/shared_lib/sources/util/properties.cpp b/source/shared_lib/sources/util/properties.cpp index a7178be06..1e9096b11 100644 --- a/source/shared_lib/sources/util/properties.cpp +++ b/source/shared_lib/sources/util/properties.cpp @@ -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 *mapTagReplacementValues) { +bool Properties::applyTagsToValue(string &value, const std::map *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 * //} if(valueRequiresPathUpdate == true) { - Properties::updateValuePathVariable(value); + Properties::updateValuePathVariable(value, skipUpdatePathClimbingParts); } return (originalValue != value); } diff --git a/source/shared_lib/sources/xml/xml_parser.cpp b/source/shared_lib/sources/xml/xml_parser.cpp index 11c773940..ca71d0bb9 100644 --- a/source/shared_lib/sources/xml/xml_parser.cpp +++ b/source/shared_lib/sources/xml/xml_parser.cpp @@ -339,7 +339,8 @@ XmlIoRapid::~XmlIoRapid() { cleanup(); } -XmlNode *XmlIoRapid::load(const string &path, const std::map &mapTagReplacementValues,bool noValidation,bool skipStackTrace) { +XmlNode *XmlIoRapid::load(const string &path, const std::map &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 &map // Load data and add terminating 0 vector buffer; - buffer.resize((unsigned int)file_size + 1); + buffer.resize((unsigned int)file_size + 100); xmlFile.read(&buffer.front(), static_cast(file_size)); buffer[(unsigned int)file_size] = 0; @@ -405,7 +406,7 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map &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 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 &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 &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 &mapTagReplacement #endif -XmlNode::XmlNode(xml_node<> *node, const std::map &mapTagReplacementValues) : superNode(NULL) { +XmlNode::XmlNode(xml_node<> *node, const std::map &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 &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 &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; } }