From 9dc4ce92990ff10ba421878cd3358758a2309744 Mon Sep 17 00:00:00 2001
From: atraczyk <andreastraczyk@gmail.com>
Date: Fri, 17 Feb 2017 12:23:14 -0500
Subject: [PATCH] text message: client fix for vcard spam bug

- Vcard chunks may be received through the IncomingMessage and
  IncomingAccountMessage signals. This patch implements handling
  of the latter.

- This patch also handles cases where a vcard has only one chunk,
  and where the photo is empty.

Change-Id: Id0e9a5c74284e85be729c972a16a14ebb0a9dd24
Tuleap: #1436
---
 Package.appxmanifest         |  2 +-
 RingD.cpp                    | 79 ++++++++++++++++++------------------
 RingD.h                      |  4 ++
 SmartPanelItemsViewModel.cpp | 10 +++++
 SmartPanelItemsViewModel.h   |  2 +
 Utils.h                      |  4 +-
 VCardUtils.cpp               | 26 +++++++++---
 VCardUtils.h                 |  1 +
 8 files changed, 80 insertions(+), 48 deletions(-)

diff --git a/Package.appxmanifest b/Package.appxmanifest
index 5eb7a74..8fa1a09 100644
--- a/Package.appxmanifest
+++ b/Package.appxmanifest
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap uap3 mp">
-  <Identity Name="Savoir-faireLinux.GNURing" Publisher="CN=8121A5F7-3CA1-4CAA-92B2-4F595B011941" Version="1.1.62.0" />
+  <Identity Name="Savoir-faireLinux.GNURing" Publisher="CN=8121A5F7-3CA1-4CAA-92B2-4F595B011941" Version="1.1.65.0" />
   <mp:PhoneIdentity PhoneProductId="2385953f-9019-423d-aa82-d1bbacfa258b" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
   <Properties>
     <DisplayName>GNU Ring</DisplayName>
diff --git a/RingD.cpp b/RingD.cpp
index 18e75ba..5294992 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -416,6 +416,43 @@ ShowMsgToast(String^ from, String^ payload)
     ToastNotificationManager::CreateToastNotifier()->Show(toast);
 }
 
+void
+RingD::HandleIncomingMessage(   const std::string& callId,
+                                const std::string& accountId,
+                                const std::string& from,
+                                const std::map<std::string, std::string>& payloads)
+{
+    auto callId2 = toPlatformString(callId);
+    auto accountId2 = toPlatformString(accountId);
+    auto from2 = toPlatformString(from);
+    from2 = Utils::TrimRingId2(from2);
+
+    auto item = SmartPanelItemsViewModel::instance->findItemByRingID(from2);
+    Contact^ contact;
+
+    static const unsigned int profileSize = VCardUtils::PROFILE_VCF.size();
+    for (auto i : payloads) {
+        if (i.first.compare(0, profileSize, VCardUtils::PROFILE_VCF) == 0) {
+            if (item) {
+                contact = item->_contact;
+                contact->getVCard()->receiveChunk(i.first, i.second);
+            }
+            else
+                WNG_("item not found!");
+            return;
+        }
+        auto payload = Utils::toPlatformString(i.second);
+        CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
+            CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
+        {
+            if (!accountId2->IsEmpty())
+                incomingAccountMessage(accountId2, from2, payload);
+            else if (!callId2->IsEmpty())
+                incomingMessage(callId2, payload);
+        }));
+    }
+}
+
 void
 RingD::registerCallbacks()
 {
@@ -561,18 +598,7 @@ RingD::registerCallbacks()
             MSG_("accountId = " + accountId);
             MSG_("from = " + from);
 
-            auto accountId2 = toPlatformString(accountId);
-            auto from2 = toPlatformString(from);
-
-            for (auto i : payloads) {
-                MSG_("payload = " + i.second);
-                auto payload = Utils::toPlatformString(i.second);
-                CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
-                    CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
-                {
-                    incomingAccountMessage(accountId2, from2, payload);
-                }));
-            }
+            HandleIncomingMessage("", accountId, from, payloads);
         }),
         DRing::exportable_callback<DRing::CallSignal::IncomingMessage>([&](
                     const std::string& callId,
@@ -583,34 +609,7 @@ RingD::registerCallbacks()
             MSG_("callId = " + callId);
             MSG_("from = " + from);
 
-            auto callId2 = toPlatformString(callId);
-            auto from2 = toPlatformString(from);
-
-            from2 = Utils::TrimRingId2(from2);
-
-            auto item = SmartPanelItemsViewModel::instance->findItem(callId2);
-            Contact^ contact;
-            if (item)
-                contact = item->_contact;
-            else
-                WNG_("item not found!");
-
-            static const unsigned int profileSize = VCardUtils::PROFILE_VCF.size();
-            for (auto i : payloads) {
-                MSG_(i.first);
-                if (i.first.compare(0, profileSize, VCardUtils::PROFILE_VCF) == 0) {
-                    MSG_("payload.first = " + i.first);
-                    MSG_("payload.second = " + i.second);
-                    int res = contact->getVCard()->receiveChunk(i.first, i.second);
-                    return;
-                }
-                auto payload = Utils::toPlatformString(i.second);
-                CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
-                    CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
-                {
-                    incomingMessage(callId2, payload);
-                }));
-            }
+            HandleIncomingMessage(callId, "", from, payloads);
         }),
         DRing::exportable_callback<DRing::ConfigurationSignal::RegistrationStateChanged>([this](
                     const std::string& account_id, const std::string& state,
diff --git a/RingD.h b/RingD.h
index 98dfa12..f6e51f8 100644
--- a/RingD.h
+++ b/RingD.h
@@ -150,6 +150,10 @@ internal:
     CallStatus translateCallStatus(String^ state);
     String^ getUserName();
     Vector<String^>^ translateKnownRingDevices(const std::map<std::string, std::string> devices);
+    void HandleIncomingMessage( const std::string& callId,
+                                const std::string& accountId,
+                                const std::string& from,
+                                const std::map<std::string, std::string>& payloads);
 
     void toggleFullScreen();
     void setWindowedMode();
diff --git a/SmartPanelItemsViewModel.cpp b/SmartPanelItemsViewModel.cpp
index 4aa3c88..f3c0567 100644
--- a/SmartPanelItemsViewModel.cpp
+++ b/SmartPanelItemsViewModel.cpp
@@ -70,6 +70,16 @@ SmartPanelItemsViewModel::findItem(Contact^ contact)
     return nullptr;
 }
 
+SmartPanelItem^
+SmartPanelItemsViewModel::findItemByRingID(String^ ringID)
+{
+    for each (SmartPanelItem^ item in itemsList)
+        if (item->_contact->ringID_ == ringID)
+            return item;
+
+    return nullptr;
+}
+
 unsigned int
 SmartPanelItemsViewModel::getIndex(String^ callId)
 {
diff --git a/SmartPanelItemsViewModel.h b/SmartPanelItemsViewModel.h
index ce15d10..68eb8ce 100644
--- a/SmartPanelItemsViewModel.h
+++ b/SmartPanelItemsViewModel.h
@@ -47,6 +47,8 @@ internal:
     /* functions */
     SmartPanelItem^ findItem(String^ callId);
     SmartPanelItem^ findItem(Contact^ contact);
+    SmartPanelItem^ findItemByRingID(String^ ringID);
+
     unsigned int getIndex(String^ callId);
     unsigned int getIndex(Contact^ contact);
     void removeItem(SmartPanelItem^ item);
diff --git a/Utils.h b/Utils.h
index d5962b3..4f163f8 100644
--- a/Utils.h
+++ b/Utils.h
@@ -129,9 +129,11 @@ TrimRingId(Platform::String^ s)
 
 /* fix some issue in the daemon -->  remove "@..." */
 Platform::String^
-
 TrimRingId2(Platform::String^ s)
 {
+    if (toString(s).find("@") == std::string::npos)
+        return s;
+
     const WCHAR* first = s->Begin();
     const WCHAR* last = s->End();
 
diff --git a/VCardUtils.cpp b/VCardUtils.cpp
index 7b23035..fb0ddf6 100644
--- a/VCardUtils.cpp
+++ b/VCardUtils.cpp
@@ -93,6 +93,11 @@ VCard::receiveChunk(const std::string& args, const std::string& payload)
         else
             m_mParts[Property::PHOTO].append(_line.substr(pos + 4));
 
+        if (_of == 1) {
+            completeReception();
+            MSG_("VCARD_COMPLETE");
+            return VCARD_COMPLETE;
+        }
         return VCARD_INCOMPLETE;
     }
     else {
@@ -110,12 +115,7 @@ VCard::receiveChunk(const std::string& args, const std::string& payload)
             if (fnFound)
                 m_mParts[Property::FN] = _line.substr(3);
 
-            saveToFile();
-            decodeBase64ToPNGFile();
-            if (!m_mParts[Property::FN].empty())
-                m_Owner->_displayName = Utils::toPlatformString(m_mParts[Property::FN]);
-            m_Owner->_vcardUID = Utils::toPlatformString(m_mParts[Property::UID]);
-            ViewModel::ContactsViewModel::instance->saveContactsToFile();
+            completeReception();
             MSG_("VCARD_COMPLETE");
             return VCARD_COMPLETE;
         }
@@ -127,6 +127,17 @@ VCard::receiveChunk(const std::string& args, const std::string& payload)
     return VCARD_CHUNK_ERROR;
 }
 
+void
+VCard::completeReception()
+{
+    saveToFile();
+    decodeBase64ToPNGFile();
+    if (!m_mParts[Property::FN].empty())
+        m_Owner->_displayName = Utils::toPlatformString(m_mParts[Property::FN]);
+    m_Owner->_vcardUID = Utils::toPlatformString(m_mParts[Property::UID]);
+    ViewModel::ContactsViewModel::instance->saveContactsToFile();
+}
+
 void
 VCard::send(std::string callID, const char* vCardFile)
 {
@@ -192,6 +203,9 @@ VCard::asString()
 void
 VCard::decodeBase64ToPNGFile()
 {
+    if (!m_mParts[Property::PHOTO].size())
+        return;
+
     size_t padding = m_mParts[Property::PHOTO].size() % 4;
     if (padding)
         m_mParts[Property::PHOTO].append(padding, 0);
diff --git a/VCardUtils.h b/VCardUtils.h
index 68f09dc..a1ceacd 100644
--- a/VCardUtils.h
+++ b/VCardUtils.h
@@ -69,6 +69,7 @@ internal:
     void                    decodeBase64ToPNGFile();
     void                    encodePNGToBase64();
 
+    void                    completeReception();
     void                    setData(std::map<std::string, std::string> data);
 
 private:
-- 
GitLab