diff --git a/src/core/Merger.cpp b/src/core/Merger.cpp index e4cf0f994..c73248388 100644 --- a/src/core/Merger.cpp +++ b/src/core/Merger.cpp @@ -618,8 +618,8 @@ Merger::ChangeList Merger::mergeMetadata(const MergeContext& context) const auto keys = sourceMetadata->customIcons().keys(); for (QUuid customIconId : keys) { - QImage customIcon = sourceMetadata->customIcon(customIconId); if (!targetMetadata->containsCustomIcon(customIconId)) { + QImage customIcon = sourceMetadata->customIcon(customIconId); targetMetadata->addCustomIcon(customIconId, customIcon); changes << tr("Adding missing icon %1").arg(QString::fromLatin1(customIconId.toRfc4122().toHex())); } diff --git a/src/core/Metadata.cpp b/src/core/Metadata.cpp index 45010a4ff..6448c391a 100644 --- a/src/core/Metadata.cpp +++ b/src/core/Metadata.cpp @@ -382,10 +382,12 @@ void Metadata::addCustomIcon(const QUuid& uuid, const QImage& icon) Q_ASSERT(!uuid.isNull()); Q_ASSERT(!m_customIcons.contains(uuid)); - m_customIcons.insert(uuid, icon); + m_customIcons[uuid] = icon; // reset cache in case there is also an icon with that uuid m_customIconCacheKeys[uuid] = QPixmapCache::Key(); m_customIconScaledCacheKeys[uuid] = QPixmapCache::Key(); + // remove all uuids to prevent duplicates in release mode + m_customIconsOrder.removeAll(uuid); m_customIconsOrder.append(uuid); // Associate image hash to uuid QByteArray hash = hashImage(icon); diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index 295883ab8..33f5ed1f6 100644 --- a/src/keeshare/ShareObserver.cpp +++ b/src/keeshare/ShareObserver.cpp @@ -592,7 +592,8 @@ Database* ShareObserver::exportIntoContainer(const KeeShareSettings::Reference& { const auto* sourceDb = sourceRoot->database(); auto* targetDb = new Database(); - targetDb->metadata()->setRecycleBinEnabled(false); + auto* targetMetadata = targetDb->metadata(); + targetMetadata->setRecycleBinEnabled(false); auto key = QSharedPointer::create(); key->addKey(QSharedPointer::create(reference.password)); @@ -610,8 +611,8 @@ Database* ShareObserver::exportIntoContainer(const KeeShareSettings::Reference& targetEntry->setGroup(targetRoot); targetEntry->setUpdateTimeinfo(updateTimeinfo); const auto iconUuid = targetEntry->iconUuid(); - if (!iconUuid.isNull()) { - targetDb->metadata()->addCustomIcon(iconUuid, sourceEntry->icon()); + if (!iconUuid.isNull() && !targetMetadata->containsCustomIcon(iconUuid)) { + targetMetadata->addCustomIcon(iconUuid, sourceEntry->icon()); } } diff --git a/tests/TestMerge.cpp b/tests/TestMerge.cpp index a09eb32e6..03eae32ef 100644 --- a/tests/TestMerge.cpp +++ b/tests/TestMerge.cpp @@ -1127,6 +1127,34 @@ void TestMerge::testMergeCustomIcons() QVERIFY(dbDestination->metadata()->containsCustomIcon(customIconId)); } +/** + * No duplicate icons should be created + */ +void TestMerge::testMergeDuplicateCustomIcons() +{ + QScopedPointer dbDestination(new Database()); + QScopedPointer dbSource(createTestDatabase()); + + m_clock->advanceSecond(1); + + QUuid customIconId = QUuid::createUuid(); + QImage customIcon; + + dbSource->metadata()->addCustomIcon(customIconId, customIcon); + dbDestination->metadata()->addCustomIcon(customIconId, customIcon); + // Sanity check. + QVERIFY(dbSource->metadata()->containsCustomIcon(customIconId)); + QVERIFY(dbDestination->metadata()->containsCustomIcon(customIconId)); + + m_clock->advanceSecond(1); + + Merger merger(dbSource.data(), dbDestination.data()); + merger.merge(); + + QVERIFY(dbDestination->metadata()->containsCustomIcon(customIconId)); + QCOMPARE(dbDestination->metadata()->customIcons().count(), 1); +} + void TestMerge::testMetadata() { QSKIP("Sophisticated merging for Metadata not implemented"); diff --git a/tests/TestMerge.h b/tests/TestMerge.h index 159256f2b..357f85262 100644 --- a/tests/TestMerge.h +++ b/tests/TestMerge.h @@ -57,6 +57,7 @@ private slots: void testUpdateGroupLocation(); void testMergeAndSync(); void testMergeCustomIcons(); + void testMergeDuplicateCustomIcons(); void testMetadata(); void testDeletedEntry(); void testDeletedGroup();