diff options
Diffstat (limited to 'Swiften/Parser/LibXMLParser.cpp')
| -rw-r--r-- | Swiften/Parser/LibXMLParser.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/Swiften/Parser/LibXMLParser.cpp b/Swiften/Parser/LibXMLParser.cpp index 192f44b..4e02059 100644 --- a/Swiften/Parser/LibXMLParser.cpp +++ b/Swiften/Parser/LibXMLParser.cpp @@ -53,46 +53,68 @@ static void handleStartElement(void* parser, const xmlChar* name, const xmlChar* static void handleEndElement(void *parser, const xmlChar* name, const xmlChar*, const xmlChar* xmlns) { static_cast<XMLParser*>(parser)->getClient()->handleEndElement(reinterpret_cast<const char*>(name), (xmlns ? reinterpret_cast<const char*>(xmlns) : std::string())); } static void handleCharacterData(void* parser, const xmlChar* data, int len) { assert(len >= 0); static_cast<XMLParser*>(parser)->getClient()->handleCharacterData(std::string(reinterpret_cast<const char*>(data), static_cast<size_t>(len))); } +static void handleComment(void* parser, const xmlChar* /*data*/) { + if (!static_cast<LibXMLParser*>(parser)->allowsComments()) { + static_cast<LibXMLParser*>(parser)->stopParser(); + } +} + +static void handleEntityDeclaration(void * parser, const xmlChar* /*name*/, int /*type*/, const xmlChar* /*publicId*/, const xmlChar* /*systemId*/, xmlChar* /*content*/) { + static_cast<LibXMLParser*>(parser)->stopParser(); +} + +static void handleProcessingInstruction(void* parser, const xmlChar* /*target*/, const xmlChar* /*data*/) { + static_cast<LibXMLParser*>(parser)->stopParser(); +} + +static void handleExternalSubset(void* parser, const xmlChar * /*name*/, const xmlChar * /*ExternalID*/, const xmlChar * /*SystemID*/) { + static_cast<LibXMLParser*>(parser)->stopParser(); +} + static void handleError(void*, const char* /*m*/, ... ) { /* va_list args; va_start(args, m); vfprintf(stdout, m, args); va_end(args); */ } static void handleWarning(void*, const char*, ... ) { } bool LibXMLParser::initialized = false; -LibXMLParser::LibXMLParser(XMLParserClient* client) : XMLParser(client), p(new Private()) { +LibXMLParser::LibXMLParser(XMLParserClient* client, bool allowComments) : XMLParser(client, allowComments), p(new Private()) { // Initialize libXML for multithreaded applications if (!initialized) { xmlInitParser(); initialized = true; } memset(&p->handler_, 0, sizeof(p->handler_) ); p->handler_.initialized = XML_SAX2_MAGIC; p->handler_.startElementNs = &handleStartElement; p->handler_.endElementNs = &handleEndElement; p->handler_.characters = &handleCharacterData; p->handler_.warning = &handleWarning; p->handler_.error = &handleError; + p->handler_.comment = &handleComment; + p->handler_.entityDecl = &handleEntityDeclaration; + p->handler_.processingInstruction = &handleProcessingInstruction; + p->handler_.externalSubset = &handleExternalSubset; p->context_ = xmlCreatePushParserCtxt(&p->handler_, this, nullptr, 0, nullptr); xmlCtxtUseOptions(p->context_, XML_PARSE_NOENT); assert(p->context_); } LibXMLParser::~LibXMLParser() { if (p->context_) { xmlFreeParserCtxt(p->context_); @@ -100,19 +122,25 @@ LibXMLParser::~LibXMLParser() { } bool LibXMLParser::parse(const std::string& data, bool finalData) { if (data.size() > std::numeric_limits<int>::max()) { return false; } if (xmlParseChunk(p->context_, data.c_str(), static_cast<int>(data.size()), finalData) == XML_ERR_OK) { return true; } + if (stopped_) return false; xmlError* error = xmlCtxtGetLastError(p->context_); if (error->code == XML_WAR_NS_URI || error->code == XML_WAR_NS_URI_RELATIVE) { xmlCtxtResetLastError(p->context_); p->context_->errNo = XML_ERR_OK; return true; } return false; } +void LibXMLParser::stopParser() { + stopped_ = true; + xmlStopParser(p->context_); +} + } |
Swift