summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2018-02-26 16:27:04 (GMT)
committerTobias Markmann <tm@ayena.de>2018-02-26 16:27:04 (GMT)
commit8ede4f21d6b81263b15487509e37e6df4553c18f (patch)
tree890780a61640d2a1fc2c4a2f31142069decd3d7c
parentbd4115c0db3d898d7de0944d340a9a2f1de4938c (diff)
downloadswift-8ede4f21d6b81263b15487509e37e6df4553c18f.zip
swift-8ede4f21d6b81263b15487509e37e6df4553c18f.tar.bz2
Ignore invalid vCard avatar update notifications
Test-Information: Tests pass on macOS 10.13.3 with clang-trunk and ASAN. Change-Id: Ice68e93341693349ed5d95dfc062c0a7b07dc673
-rw-r--r--Swift/Controllers/Storages/AvatarFileStorage.cpp31
-rw-r--r--Swiften/Avatars/UnitTest/AvatarManagerImplTest.cpp3
-rw-r--r--Swiften/Avatars/VCardUpdateAvatarManager.cpp6
3 files changed, 27 insertions, 13 deletions
diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp
index a103920..9d9b9ea 100644
--- a/Swift/Controllers/Storages/AvatarFileStorage.cpp
+++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp
@@ -1,22 +1,21 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Storages/AvatarFileStorage.h>
-#include <iostream>
-
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/StringCodecs/Hexify.h>
namespace Swift {
AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto) : avatarsDir(avatarsDir), avatarsFile(avatarsFile), crypto(crypto) {
if (boost::filesystem::exists(avatarsFile)) {
try {
@@ -25,57 +24,67 @@ AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir,
if (file.is_open()) {
while (!file.eof()) {
getline(file, line);
std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
JID jid(r.second);
if (jid.isValid()) {
jidAvatars.insert(std::make_pair(jid, r.first));
}
else if (!r.first.empty() || !r.second.empty()) {
- std::cerr << "Invalid entry in avatars file: " << r.second << std::endl;
+ SWIFT_LOG(error) << "Invalid entry in avatars file: " << r.second << std::endl;
}
}
}
}
catch (...) {
- std::cerr << "Error reading avatars file" << std::endl;
+ SWIFT_LOG(error) << "Error reading avatars file" << std::endl;
}
}
}
bool AvatarFileStorage::hasAvatar(const std::string& hash) const {
return boost::filesystem::exists(getAvatarPath(hash));
}
void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) {
assert(Hexify::hexify(crypto->getSHA1Hash(avatar)) == hash);
boost::filesystem::path avatarPath = getAvatarPath(hash);
if (!boost::filesystem::exists(avatarPath.parent_path())) {
try {
boost::filesystem::create_directories(avatarPath.parent_path());
}
catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
+ SWIFT_LOG(error) << "filesystem error: " << e.what() << std::endl;
}
}
- boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
- file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size()));
- file.close();
+
+ try {
+ boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
+ file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size()));
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ SWIFT_LOG(error) << "filesystem error: " << e.what() << std::endl;
+ }
}
boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const {
return avatarsDir / hash;
}
ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const {
ByteArray data;
- readByteArrayFromFile(data, getAvatarPath(hash));
+ try {
+ readByteArrayFromFile(data, getAvatarPath(hash));
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ SWIFT_LOG(error) << "filesystem error: " << e.what() << std::endl;
+ }
return data;
}
void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) {
std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash));
if (r.second) {
saveJIDAvatars();
}
else if (r.first->second != hash) {
@@ -92,14 +101,14 @@ std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const {
void AvatarFileStorage::saveJIDAvatars() {
try {
boost::filesystem::ofstream file(avatarsFile);
for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) {
file << i->second << " " << i->first.toString() << std::endl;
}
file.close();
}
catch (...) {
- std::cerr << "Error writing avatars file" << std::endl;
+ SWIFT_LOG(error) << "Error writing avatars file" << std::endl;
}
}
}
diff --git a/Swiften/Avatars/UnitTest/AvatarManagerImplTest.cpp b/Swiften/Avatars/UnitTest/AvatarManagerImplTest.cpp
index 241f375..5a35410 100644
--- a/Swiften/Avatars/UnitTest/AvatarManagerImplTest.cpp
+++ b/Swiften/Avatars/UnitTest/AvatarManagerImplTest.cpp
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2014-2016 Isode Limited.
+ * Copyright (c) 2014-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <string>
#include <boost/bind.hpp>
#include <cppunit/extensions/HelperMacros.h>
@@ -85,18 +85,19 @@ class AvatarManagerImplTest : public CppUnit::TestFixture {
/* check hash through avatarManager that it received the correct photo */
ByteArray reportedAvatar = avatarManager->getAvatar(personJID.toBare());
CPPUNIT_ASSERT_EQUAL(byteArrayToString(fullAvatar), byteArrayToString(reportedAvatar));
/* send new presence to notify of blank avatar */
vcardUpdate = std::make_shared<VCardUpdate>();
+ vcardUpdate->setPhotoHash("da39a3ee5e6b4b0d3255bfef95601890afd80709");
presence = std::make_shared<Presence>();
presence->setTo(ownerJID);
presence->setFrom(personJID);
presence->setType(Presence::Available);
presence->addPayload(vcardUpdate);
stanzaChannel->onPresenceReceived(presence);
/* reply to the avatar request with our EMPTY avatar */
diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp
index 3e8d87b..349af2f 100644
--- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp
+++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swiften/Avatars/VCardUpdateAvatarManager.h>
#include <boost/bind.hpp>
#include <Swiften/Avatars/AvatarStorage.h>
@@ -26,18 +26,22 @@ VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, S
vcardManager_->onVCardChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleVCardChanged, this, _1, _2));
}
void VCardUpdateAvatarManager::handlePresenceReceived(std::shared_ptr<Presence> presence) {
std::shared_ptr<VCardUpdate> update = presence->getPayload<VCardUpdate>();
if (!update || presence->getPayload<ErrorPayload>()) {
return;
}
JID from = getAvatarJID(presence->getFrom());
+ if (update->getPhotoHash().size() != 40) {
+ SWIFT_LOG(debug) << "Invalid vCard avatar photo hash length. Must be hex-encoded SHA-1, i.e. 40 characters." << std::endl;
+ return;
+ }
if (getAvatarHash(from) == update->getPhotoHash()) {
return;
}
SWIFT_LOG(debug) << "Updated hash: " << from << " -> " << update->getPhotoHash() << std::endl;
if (avatarStorage_->hasAvatar(update->getPhotoHash())) {
setAvatarHash(from, update->getPhotoHash());
}
else {
vcardManager_->requestVCard(from);