From 9f94bd461ef3ac735cb436e308ec7dca58c17112 Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 17 Jan 2023 10:06:09 +0800 Subject: [PATCH] Fix #1032 --- core/2d/CCTMXXMLParser.cpp | 47 ++++++++++--------- core/base/ccUtils.cpp | 27 ++++++++--- core/platform/CCSAXParser.cpp | 27 ++++++++--- core/platform/CCSAXParser.h | 14 ++++-- core/ui/UIRichText.cpp | 2 +- extensions/fairygui/utils/html/HtmlParser.cpp | 2 +- 6 files changed, 78 insertions(+), 41 deletions(-) diff --git a/core/2d/CCTMXXMLParser.cpp b/core/2d/CCTMXXMLParser.cpp index 9f71540214..892b95f0bb 100644 --- a/core/2d/CCTMXXMLParser.cpp +++ b/core/2d/CCTMXXMLParser.cpp @@ -33,9 +33,10 @@ THE SOFTWARE. // #include "2d/CCTMXTiledMap.h" #include "base/ZipUtils.h" #include "base/CCDirector.h" +#include "base/ccUtils.h" #include "platform/CCFileUtils.h" -using namespace std; +// using namespace std; NS_AX_BEGIN @@ -185,7 +186,7 @@ bool TMXMapInfo::parseXMLString(std::string_view xmlString) parser.setDelegator(this); - return parser.parse(xmlString.data(), len); + return parser.parse(xmlString.data(), len, SAXParser::ParseOption::TRIM_WHITESPACE); } bool TMXMapInfo::parseXMLFile(std::string_view xmlFilename) @@ -199,7 +200,7 @@ bool TMXMapInfo::parseXMLFile(std::string_view xmlFilename) parser.setDelegator(this); - return parser.parse(FileUtils::getInstance()->fullPathForFilename(xmlFilename)); + return parser.parse(xmlFilename, SAXParser::ParseOption::TRIM_WHITESPACE); } // the XML parser calls here with all the elements @@ -288,9 +289,9 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts _externalTilesetFilename = externalTilesetFilename; // Tileset file will be relative to the map file. So we need to convert it to an absolute path - if (_TMXFileName.find_last_of('/') != string::npos) + if (_TMXFileName.find_last_of('/') != std::string::npos) { - string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1); + std::string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1); externalTilesetFilename = dir + externalTilesetFilename; } else @@ -421,9 +422,9 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts std::string imagename = attributeDict["source"].asString(); tileset->_originSourceImage = imagename; - if (_TMXFileName.find_last_of('/') != string::npos) + if (_TMXFileName.find_last_of('/') != std::string::npos) { - string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1); + std::string dir = _TMXFileName.substr(0, _TMXFileName.find_last_of('/') + 1); tileset->_sourceImage = dir + imagename; } else @@ -582,13 +583,13 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts pointsArray.reserve(10); // parse points string into a space-separated set of points - stringstream pointsStream(value); - string pointPair; + std::stringstream pointsStream(value); + std::string pointPair; while (std::getline(pointsStream, pointPair, ' ')) { // parse each point combo into a comma-separated x,y point - stringstream pointStream(pointPair); - string xStr, yStr; + std::stringstream pointStream(pointPair); + std::string xStr, yStr; ValueMap pointDict; @@ -627,13 +628,13 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts pointsArray.reserve(10); // parse points string into a space-separated set of points - stringstream pointsStream(value); - string pointPair; + std::stringstream pointsStream(value); + std::string pointPair; while (std::getline(pointsStream, pointPair, ' ')) { // parse each point combo into a comma-separated x,y point - stringstream pointStream(pointPair); - string xStr, yStr; + std::stringstream pointStream(pointPair); + std::string xStr, yStr; ValueMap pointDict; @@ -689,8 +690,8 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) auto currentString = tmxMapInfo->getCurrentString(); unsigned char* buffer; - auto len = - utils::base64Decode((unsigned char*)currentString.data(), (unsigned int)currentString.length(), &buffer); + auto len = utils::base64Decode((unsigned char*)currentString.data(), (unsigned int)currentString.length(), + &buffer); if (!buffer) { AXLOG("axmol: TiledMap: decode data error"); @@ -734,15 +735,15 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) tmxMapInfo->setStoringCharacters(false); auto currentString = tmxMapInfo->getCurrentString(); - vector gidTokens; + std::vector gidTokens; std::stringstream filestr; filestr << currentString; - string sRow; - while (getline(filestr, sRow, '\n')) + std::string sRow; + while (std::getline(filestr, sRow, '\n')) { - string sGID; - istringstream rowstr(sRow); - while (getline(rowstr, sGID, ',')) + std::string sGID; + std::istringstream rowstr(sRow); + while (std::getline(rowstr, sGID, ',')) { gidTokens.emplace_back(sGID); } diff --git a/core/base/ccUtils.cpp b/core/base/ccUtils.cpp index 6a931dcd83..31f0f1ece6 100644 --- a/core/base/ccUtils.cpp +++ b/core/base/ccUtils.cpp @@ -844,22 +844,35 @@ int base64Encode(const unsigned char* in, unsigned int inLength, char** out) { auto n = ax::base64::encoded_size(inLength); // should be enough to store 8-bit buffers in 6-bit buffers - *out = (char*)malloc(n + 1); - if (*out) + char* tmp = nullptr; + if (n > 0 && (tmp = (char*)malloc(n + 1))) { - auto ret = ax::base64::encode(*out, in, inLength); - *out[ret] = '\0'; + auto ret = ax::base64::encode(tmp, in, inLength); + tmp[ret] = '\0'; + *out = tmp; return ret; } + *out = nullptr; return 0; } AX_DLL int base64Decode(const unsigned char* in, unsigned int inLength, unsigned char** out) { size_t n = ax::base64::decoded_size(inLength); - *out = (unsigned char*)malloc(n); - if (*out) - return static_cast(ax::base64::decode(*out, (char*)in, inLength)); + unsigned char* tmp = nullptr; + if (n > 0 && (tmp = (unsigned char*)malloc(n))) + { + n = static_cast(ax::base64::decode(tmp, reinterpret_cast(in), inLength)); + if (n > 0) + *out = tmp; + else + { + *out = nullptr; + free(tmp); + } + return n; + } + *out = nullptr; return 0; } diff --git a/core/platform/CCSAXParser.cpp b/core/platform/CCSAXParser.cpp index a0bb182e65..94f75ce174 100644 --- a/core/platform/CCSAXParser.cpp +++ b/core/platform/CCSAXParser.cpp @@ -98,36 +98,51 @@ bool SAXParser::init(const char* /*encoding*/) return true; } -bool SAXParser::parse(const char* xmlData, size_t dataLength) +bool SAXParser::parse(const char* xmlData, size_t dataLength, ParseOption opt) { if (xmlData != nullptr && dataLength > 0) { std::string mutableData(xmlData, dataLength); - return this->parseIntrusive(&mutableData.front(), dataLength); + return this->parseIntrusive(&mutableData.front(), dataLength, opt); } return false; } -bool SAXParser::parse(std::string_view filename) +bool SAXParser::parse(std::string_view filename, ParseOption opt) { bool ret = false; Data data = FileUtils::getInstance()->getDataFromFile(filename); if (!data.isNull()) { - ret = parseIntrusive((char*)data.getBytes(), data.getSize()); + ret = parseIntrusive((char*)data.getBytes(), data.getSize(), opt); } return ret; } -bool SAXParser::parseIntrusive(char* xmlData, size_t dataLength) +bool SAXParser::parseIntrusive(char* xmlData, size_t dataLength, ParseOption opt) { SAX2Hander handler; handler.setSAXParserImp(this); try { - xsxml::xml_sax3_parser::parse(xmlData, static_cast(dataLength), handler); + switch (opt) + { + case ParseOption::NORMAL: + xsxml::xml_sax3_parser::parse(xmlData, static_cast(dataLength), handler); + break; + case ParseOption::HTML: + xsxml::xml_sax3_parser::parse(xmlData, static_cast(dataLength), + handler); + break; + case ParseOption::TRIM_WHITESPACE: + xsxml::xml_sax3_parser::parse( + xmlData, static_cast(dataLength), handler); + break; + } + return true; } catch (xsxml::parse_error& e) diff --git a/core/platform/CCSAXParser.h b/core/platform/CCSAXParser.h index 1c19681f65..66bc09bdbe 100644 --- a/core/platform/CCSAXParser.h +++ b/core/platform/CCSAXParser.h @@ -66,6 +66,14 @@ class AX_DLL SAXParser SAXDelegator* _delegator; public: + + enum class ParseOption + { + NORMAL, // parse_normal + HTML, // parse_normal|parse_html_entity_translation|parse_normalize_whitespace + TRIM_WHITESPACE, // parse_normal|parse_trim_whitespace + }; + /** * @js NA * @lua NA @@ -85,17 +93,17 @@ public: * @js NA * @lua NA */ - bool parse(const char* xmlData, size_t dataLength); + bool parse(const char* xmlData, size_t dataLength, ParseOption opt = ParseOption::NORMAL); /** * @js NA * @lua NA */ - bool parse(std::string_view filename); + bool parse(std::string_view filename, ParseOption opt = ParseOption::NORMAL); /** * New API for performance. */ - bool parseIntrusive(char* xmlData, size_t dataLength); + bool parseIntrusive(char* xmlData, size_t dataLength, ParseOption opt = ParseOption::NORMAL); /** * @js NA diff --git a/core/ui/UIRichText.cpp b/core/ui/UIRichText.cpp index ff64e61375..5381bfacbd 100644 --- a/core/ui/UIRichText.cpp +++ b/core/ui/UIRichText.cpp @@ -1102,7 +1102,7 @@ bool RichText::initWithXML(std::string_view origxml, const ValueMap& defaults, c MyXMLVisitor visitor(this); SAXParser parser; parser.setDelegator(&visitor); - return parser.parseIntrusive(&xml.front(), xml.length()); + return parser.parseIntrusive(&xml.front(), xml.length(), SAXParser::ParseOption::HTML); } return false; } diff --git a/extensions/fairygui/utils/html/HtmlParser.cpp b/extensions/fairygui/utils/html/HtmlParser.cpp index 8f834b1105..4bb20a938b 100644 --- a/extensions/fairygui/utils/html/HtmlParser.cpp +++ b/extensions/fairygui/utils/html/HtmlParser.cpp @@ -308,7 +308,7 @@ void HtmlParser::parse(const std::string& source, const TextFormat& format, std: string xmlText = "" + source + ""; SAXParser parser; parser.setDelegator(this); - parser.parseIntrusive(&xmlText.front(), xmlText.length()); + parser.parseIntrusive(&xmlText.front(), xmlText.length(), SAXParser::ParseOption::HTML); } NS_FGUI_END