diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index ddca7b4fe..1c370a622 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -1423,9 +1423,15 @@ void Entry::resolveReferencesBeforeDatabaseMove() // Resolve references in all default attributes for (const QString& key : EntryAttributes::DefaultAttributes) { if (m_attributes->contains(key) && m_attributes->isReference(key)) { - QString resolvedValue = resolveMultiplePlaceholdersRecursive(m_attributes->value(key), 10); - bool isProtected = m_attributes->isProtected(key); - m_attributes->set(key, resolvedValue, isProtected); + QString originalValue = m_attributes->value(key); + QString resolvedValue = resolveMultiplePlaceholdersRecursive(originalValue, 10); + + // Only replace if the resolution produced a different value and it's not empty + // Empty resolution means the reference couldn't be resolved, so keep original + if (!resolvedValue.isEmpty() && resolvedValue != originalValue) { + bool isProtected = m_attributes->isProtected(key); + m_attributes->set(key, resolvedValue, isProtected); + } } } @@ -1433,9 +1439,15 @@ void Entry::resolveReferencesBeforeDatabaseMove() const QList customKeys = m_attributes->customKeys(); for (const QString& key : customKeys) { if (m_attributes->isReference(key)) { - QString resolvedValue = resolveMultiplePlaceholdersRecursive(m_attributes->value(key), 10); - bool isProtected = m_attributes->isProtected(key); - m_attributes->set(key, resolvedValue, isProtected); + QString originalValue = m_attributes->value(key); + QString resolvedValue = resolveMultiplePlaceholdersRecursive(originalValue, 10); + + // Only replace if the resolution produced a different value and it's not empty + // Empty resolution means the reference couldn't be resolved, so keep original + if (!resolvedValue.isEmpty() && resolvedValue != originalValue) { + bool isProtected = m_attributes->isProtected(key); + m_attributes->set(key, resolvedValue, isProtected); + } } } } diff --git a/tests/TestEntry.cpp b/tests/TestEntry.cpp index c9b91a64a..1f2e4e711 100644 --- a/tests/TestEntry.cpp +++ b/tests/TestEntry.cpp @@ -702,7 +702,7 @@ void TestEntry::testCrossDatabaseReferences() refEntry->setPassword(QString("{REF:P@I:%1}").arg(originalEntry->uuidToHex())); refEntry->setUrl(QString("{REF:A@I:%1}").arg(originalEntry->uuidToHex())); refEntry->setNotes(QString("{REF:N@I:%1}").arg(originalEntry->uuidToHex())); - + // Add custom attribute with reference refEntry->attributes()->set("CustomRef", QString("{REF:T@I:%1}").arg(originalEntry->uuidToHex())); @@ -712,7 +712,8 @@ void TestEntry::testCrossDatabaseReferences() QCOMPARE(refEntry->resolveMultiplePlaceholders(refEntry->password()), QString("OriginalPassword")); QCOMPARE(refEntry->resolveMultiplePlaceholders(refEntry->url()), QString("http://original.com")); QCOMPARE(refEntry->resolveMultiplePlaceholders(refEntry->notes()), QString("OriginalNotes")); - QCOMPARE(refEntry->resolveMultiplePlaceholders(refEntry->attributes()->value("CustomRef")), QString("OriginalTitle")); + QCOMPARE(refEntry->resolveMultiplePlaceholders(refEntry->attributes()->value("CustomRef")), + QString("OriginalTitle")); // Verify the attributes still contain references (not yet resolved) QVERIFY(refEntry->attributes()->isReference(EntryAttributes::TitleKey)); @@ -747,7 +748,7 @@ void TestEntry::testCrossDatabaseReferences() orphanEntry->setGroup(root1); orphanEntry->setUuid(QUuid::createUuid()); orphanEntry->setTitle("{REF:T@I:NONEXISTENTUUID}"); - + // Move orphan entry - the unresolvable reference should remain unchanged orphanEntry->setGroup(root2); QCOMPARE(orphanEntry->title(), QString("{REF:T@I:NONEXISTENTUUID}"));