summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Parser/UnitTest/XMPPParserTest.cpp7
-rw-r--r--Swiften/Parser/XMPPParser.cpp66
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) {