diff --git a/backends/twitter/TwitterResponseParser.cpp b/backends/twitter/TwitterResponseParser.cpp index 4324b310..b908b770 100644 --- a/backends/twitter/TwitterResponseParser.cpp +++ b/backends/twitter/TwitterResponseParser.cpp @@ -1,5 +1,6 @@ #include "TwitterResponseParser.h" #include "transport/logging.h" +#include "boost/algorithm/string.hpp" #include DEFINE_LOGGER(logger, "TwitterResponseParser") @@ -11,6 +12,16 @@ static std::string tolowercase(std::string inp) return out; } +static std::string unescape(std::string data) { + using boost::algorithm::replace_all; + replace_all(data, "&", "&"); + replace_all(data, """, "\""); + replace_all(data, "'", "\'"); + replace_all(data, "<", "<"); + replace_all(data, ">", ">"); + return data; +} + static std::string toIsoTime(std::string in) { time_t now = time(0); struct tm *mtime = gmtime(&now); @@ -31,7 +42,7 @@ EmbeddedStatus getEmbeddedStatus(const Swift::ParserElement::ref &element, const status.setCreationTime( toIsoTime(std::string( element->getChild(TwitterReponseTypes::created_at, xmlns)->getText() ) ) ); status.setID( std::string( element->getChild(TwitterReponseTypes::id, xmlns)->getText() ) ); - status.setTweet( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ); + status.setTweet( unescape (std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ) ); status.setTruncated( std::string( element->getChild(TwitterReponseTypes::truncated, xmlns)->getText() )=="true" ); status.setReplyToStatusID( std::string( element->getChild(TwitterReponseTypes::in_reply_to_status_id, xmlns)->getText() ) ); status.setReplyToUserID( std::string( element->getChild(TwitterReponseTypes::in_reply_to_user_id, xmlns)->getText() ) ); @@ -72,7 +83,7 @@ Status getStatus(const Swift::ParserElement::ref &element, const std::string xml status.setCreationTime( toIsoTime ( std::string( element->getChild(TwitterReponseTypes::created_at, xmlns)->getText() ) ) ); status.setID( std::string( element->getChild(TwitterReponseTypes::id, xmlns)->getText() ) ); - status.setTweet( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ); + status.setTweet( unescape ( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ) ); status.setTruncated( std::string( element->getChild(TwitterReponseTypes::truncated, xmlns)->getText() )=="true" ); status.setReplyToStatusID( std::string( element->getChild(TwitterReponseTypes::in_reply_to_status_id, xmlns)->getText() ) ); status.setReplyToUserID( std::string( element->getChild(TwitterReponseTypes::in_reply_to_user_id, xmlns)->getText() ) ); @@ -94,7 +105,7 @@ DirectMessage getDirectMessage(const Swift::ParserElement::ref &element, const s DM.setCreationTime( toIsoTime ( std::string( element->getChild(TwitterReponseTypes::created_at, xmlns)->getText() ) ) ); DM.setID( std::string( element->getChild(TwitterReponseTypes::id, xmlns)->getText() ) ); - DM.setMessage( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ); + DM.setMessage( unescape ( std::string( element->getChild(TwitterReponseTypes::text, xmlns)->getText() ) ) ); DM.setSenderID( std::string( element->getChild(TwitterReponseTypes::sender_id, xmlns)->getText() ) ); DM.setRecipientID( std::string( element->getChild(TwitterReponseTypes::recipient_id, xmlns)->getText() ) ); DM.setSenderScreenName( std::string( element->getChild(TwitterReponseTypes::sender_screen_name, xmlns)->getText() ) ); diff --git a/src/tests/conversationmanager.cpp b/src/tests/conversationmanager.cpp index c182146c..0869ec8a 100644 --- a/src/tests/conversationmanager.cpp +++ b/src/tests/conversationmanager.cpp @@ -141,7 +141,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2)); boost::shared_ptr msg(new Swift::Message()); - msg->setBody("hi there!"); + msg->setBody("hi there<>!"); // Forward it conv->handleMessage(msg); @@ -149,7 +149,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); - CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast(getStanza(received[0]))->getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("hi there<>!"), dynamic_cast(getStanza(received[0]))->getBody()); CPPUNIT_ASSERT_EQUAL(std::string("user@localhost"), dynamic_cast(getStanza(received[0]))->getTo().toString()); CPPUNIT_ASSERT_EQUAL(std::string("buddy1\\40test@localhost/bot"), dynamic_cast(getStanza(received[0]))->getFrom().toString()); @@ -158,13 +158,13 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe // send response msg->setFrom("user@localhost/resource"); msg->setTo("buddy1\\40test@localhost/bot"); - msg->setBody("response!"); + msg->setBody("response<>!"); injectMessage(msg); loop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); CPPUNIT_ASSERT(m_msg); - CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody()); + CPPUNIT_ASSERT_EQUAL(std::string("response<>!"), m_msg->getBody()); // send another message from legacy network, should be sent to user@localhost/resource now boost::shared_ptr msg2(new Swift::Message()); diff --git a/src/tests/stringtreeparser.cpp b/src/tests/stringtreeparser.cpp new file mode 100644 index 00000000..e25b24d8 --- /dev/null +++ b/src/tests/stringtreeparser.cpp @@ -0,0 +1,47 @@ +#include "transport/userregistry.h" +#include "transport/config.h" +#include "transport/storagebackend.h" +#include "transport/user.h" +#include "transport/transport.h" +#include "transport/storagebackend.h" +#include "transport/conversation.h" +#include "transport/usermanager.h" +#include "transport/localbuddy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "basictest.h" + +#include "transport/util.h" + +using namespace Transport; + +class StringTreeParserTest : public CPPUNIT_NS :: TestFixture{ + CPPUNIT_TEST_SUITE(StringTreeParserTest); + CPPUNIT_TEST(parseEscapedCharacters); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp (void) { + } + + void tearDown (void) { + + } + + void parseEscapedCharacters() { + Swift::ParserElement::ref root = Swift::StringTreeParser::parse("<test>"); + CPPUNIT_ASSERT_EQUAL(std::string(""), root->getText()); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION (StringTreeParserTest);