diff --git a/src/jamidht/conversationrepository.cpp b/src/jamidht/conversationrepository.cpp index 6f257a85c6feae4703865e8c2bd1b9e7c1f15a69..6834268cacc3afd4cbc813c04bb4530a3ea4644e 100644 --- a/src/jamidht/conversationrepository.cpp +++ b/src/jamidht/conversationrepository.cpp @@ -42,6 +42,8 @@ constexpr size_t MAX_FETCH_SIZE {256 * 1024 * 1024}; // 256Mb namespace jami { +static const std::regex regex_display_name("<|>"); + inline std::string_view as_view(const git_blob* blob) { @@ -91,6 +93,16 @@ public: return {std::move(repo), git_repository_free}; } + std::string getDisplayName() const { + auto shared = account_.lock(); + if (!shared) + return {}; + auto name = shared->getDisplayName(); + if (name.empty()) + name = std::string(shared->currentDeviceId()); + return std::regex_replace(name, regex_display_name, ""); + } + GitSignature signature(); bool mergeFastforward(const git_oid* target_oid, int is_unborn); std::string createMergeCommit(git_index* index, const std::string& wanted_ref); @@ -471,6 +483,7 @@ initial_commit(GitRepository& repo, auto name = account->getDisplayName(); if (name.empty()) name = deviceId; + name = std::regex_replace(name, regex_display_name, ""); git_signature* sig_ptr = nullptr; git_index* index_ptr = nullptr; @@ -563,15 +576,13 @@ GitSignature ConversationRepository::Impl::signature() { auto account = account_.lock(); - if (!account) + auto name = getDisplayName(); + if (!account || name.empty()) return {nullptr, git_signature_free}; - auto deviceId = std::string(account->currentDeviceId()); - auto name = account->getDisplayName(); - if (name.empty()) - name = deviceId; git_signature* sig_ptr = nullptr; // Sign commit's buffer + auto deviceId = std::string(account->currentDeviceId()); if (git_signature_new(&sig_ptr, name.c_str(), deviceId.c_str(), std::time(nullptr), 0) < 0) { JAMI_ERR("Unable to create a commit signature."); return {nullptr, git_signature_free}; @@ -1636,15 +1647,13 @@ ConversationRepository::Impl::commit(const std::string& msg) if (!validateDevice()) return {}; auto account = account_.lock(); - if (!account) + auto name = getDisplayName(); + if (!account || name.empty()) return {}; - auto deviceId = std::string(account->currentDeviceId()); - auto name = account->getDisplayName(); - if (name.empty()) - name = deviceId; git_signature* sig_ptr = nullptr; // Sign commit's buffer + auto deviceId = std::string(account->currentDeviceId()); if (git_signature_new(&sig_ptr, name.c_str(), deviceId.c_str(), std::time(nullptr), 0) < 0) { JAMI_ERR("Unable to create a commit signature."); return {}; @@ -2816,9 +2825,9 @@ ConversationRepository::amend(const std::string& id, const std::string& msg) if (!account) return {}; auto deviceId = std::string(account->currentDeviceId()); - auto name = account->getDisplayName(); + auto name = pimpl_->getDisplayName(); if (name.empty()) - name = deviceId; + return {}; git_signature* sig_ptr = nullptr; git_oid tree_id, commit_id; diff --git a/test/unitTest/conversation/conversation.cpp b/test/unitTest/conversation/conversation.cpp index c13b53caf1e29dd18def438d1a049ec11975cb81..fd71d988d5d26d0a613438c80cbe4d55b89da4e6 100644 --- a/test/unitTest/conversation/conversation.cpp +++ b/test/unitTest/conversation/conversation.cpp @@ -77,6 +77,7 @@ private: void testGetConversationsAfterRm(); void testRemoveInvalidConversation(); void testSendMessage(); + void testSendMessageWithBadDisplayName(); void testReplaceWithBadCertificate(); void testSendMessageTriggerMessageReceived(); void testMergeTwoDifferentHeads(); @@ -125,6 +126,7 @@ private: CPPUNIT_TEST(testGetConversationsAfterRm); CPPUNIT_TEST(testRemoveInvalidConversation); CPPUNIT_TEST(testSendMessage); + CPPUNIT_TEST(testSendMessageWithBadDisplayName); CPPUNIT_TEST(testReplaceWithBadCertificate); CPPUNIT_TEST(testSendMessageTriggerMessageReceived); CPPUNIT_TEST(testMergeTwoDifferentHeads); @@ -387,6 +389,71 @@ ConversationTest::testSendMessage() cv.wait_for(lk, 30s, [&]() { return messageBobReceived == 1; }); } +void +ConversationTest::testSendMessageWithBadDisplayName() +{ + auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId); + auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId); + auto bobUri = bobAccount->getUsername(); + + std::map<std::string, std::string> details; + details[ConfProperties::DISPLAYNAME] = "<o>"; + libjami::setAccountDetails(aliceId, details); + + std::mutex mtx; + std::unique_lock<std::mutex> lk {mtx}; + std::condition_variable cv; + std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers; + auto messageBobReceived = 0, messageAliceReceived = 0; + bool requestReceived = false; + bool conversationReady = false; + confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::MessageReceived>( + [&](const std::string& accountId, + const std::string& /* conversationId */, + std::map<std::string, std::string> /*message*/) { + if (accountId == bobId) { + messageBobReceived += 1; + } else { + messageAliceReceived += 1; + } + cv.notify_one(); + })); + confHandlers.insert( + libjami::exportable_callback<libjami::ConversationSignal::ConversationRequestReceived>( + [&](const std::string& /*accountId*/, + const std::string& /* conversationId */, + std::map<std::string, std::string> /*metadatas*/) { + requestReceived = true; + cv.notify_one(); + })); + confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>( + [&](const std::string& accountId, const std::string& /* conversationId */) { + if (accountId == bobId) { + conversationReady = true; + cv.notify_one(); + } + })); + libjami::registerSignalHandlers(confHandlers); + + auto convId = libjami::startConversation(aliceId); + + libjami::addConversationMember(aliceId, convId, bobUri); + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; })); + + libjami::acceptConversationRequest(bobId, convId); + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; })); + + // Assert that repository exists + auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID() + + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId; + CPPUNIT_ASSERT(fileutils::isDirectory(repoPath)); + // Wait that alice sees Bob + cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; }); + + libjami::sendMessage(aliceId, convId, "hi"s, ""); + cv.wait_for(lk, 30s, [&]() { return messageBobReceived == 1; }); +} + void ConversationTest::testReplaceWithBadCertificate() {