diff options
-rw-r--r-- | Swiften/Parser/UnitTest/XMPPParserTest.cpp | 7 | ||||
-rw-r--r-- | Swiften/Parser/XMPPParser.cpp | 66 |
2 files changed, 43 insertions, 30 deletions
diff --git a/Swiften/Parser/UnitTest/XMPPParserTest.cpp b/Swiften/Parser/UnitTest/XMPPParserTest.cpp index 90a4b03..1eaa798 100644 --- a/Swiften/Parser/UnitTest/XMPPParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMPPParserTest.cpp @@ -33,6 +33,7 @@ class XMPPParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_UnknownElement); CPPUNIT_TEST(testParse_StrayCharacterData); CPPUNIT_TEST(testParse_InvalidStreamStart); + CPPUNIT_TEST(testParse_ElementEndAfterInvalidStreamStart); CPPUNIT_TEST_SUITE_END(); public: @@ -149,6 +150,12 @@ class XMPPParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(!testling.parse("<tream>")); } + void testParse_ElementEndAfterInvalidStreamStart() { + XMPPParser testling(&client_, &factories_); + + CPPUNIT_ASSERT(!testling.parse("<tream/>")); + } + private: class Client : public XMPPParserClient { public: diff --git a/Swiften/Parser/XMPPParser.cpp b/Swiften/Parser/XMPPParser.cpp index 93797b3..6bd6082 100644 --- a/Swiften/Parser/XMPPParser.cpp +++ b/Swiften/Parser/XMPPParser.cpp @@ -67,54 +67,60 @@ bool XMPPParser::parse(const String& data) { } void XMPPParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) { - if (level_ == TopLevel) { - if (element == "stream" && ns == "http://etherx.jabber.org/streams") { - ProtocolHeader header; - header.setFrom(attributes.getAttribute("from")); - header.setTo(attributes.getAttribute("to")); - header.setID(attributes.getAttribute("id")); - header.setVersion(attributes.getAttribute("version")); - client_->handleStreamStart(header); + if (!parseErrorOccurred_) { + if (level_ == TopLevel) { + if (element == "stream" && ns == "http://etherx.jabber.org/streams") { + ProtocolHeader header; + header.setFrom(attributes.getAttribute("from")); + header.setTo(attributes.getAttribute("to")); + header.setID(attributes.getAttribute("id")); + header.setVersion(attributes.getAttribute("version")); + client_->handleStreamStart(header); + } + else { + parseErrorOccurred_ = true; + } } else { - parseErrorOccurred_ = true; + if (level_ == StreamLevel) { + assert(!currentElementParser_); + currentElementParser_ = createElementParser(element, ns); + } + currentElementParser_->handleStartElement(element, ns, attributes); } } - else { - if (level_ == StreamLevel) { - assert(!currentElementParser_); - currentElementParser_ = createElementParser(element, ns); - } - currentElementParser_->handleStartElement(element, ns, attributes); - } ++level_; } void XMPPParser::handleEndElement(const String& element, const String& ns) { assert(level_ > TopLevel); --level_; - if (level_ == TopLevel) { - assert(element == "stream"); - client_->handleStreamEnd(); - } - else { - assert(currentElementParser_); - currentElementParser_->handleEndElement(element, ns); - if (level_ == StreamLevel) { - client_->handleElement(currentElementParser_->getElement()); - delete currentElementParser_; - currentElementParser_ = NULL; + if (!parseErrorOccurred_) { + if (level_ == TopLevel) { + assert(element == "stream"); + client_->handleStreamEnd(); + } + else { + assert(currentElementParser_); + currentElementParser_->handleEndElement(element, ns); + if (level_ == StreamLevel) { + client_->handleElement(currentElementParser_->getElement()); + delete currentElementParser_; + currentElementParser_ = NULL; + } } } } void XMPPParser::handleCharacterData(const String& data) { - if (currentElementParser_) { - currentElementParser_->handleCharacterData(data); - } + if (!parseErrorOccurred_) { + if (currentElementParser_) { + currentElementParser_->handleCharacterData(data); + } //else { // std::cerr << "XMPPParser: Ignoring stray character data: " << data << std::endl; //} + } } ElementParser* XMPPParser::createElementParser(const String& element, const String& ns) { |