Fix cross-database reference resolution to handle unresolvable references correctly

Co-authored-by: droidmonkey <2809491+droidmonkey@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-06-19 14:41:05 +00:00
parent b0f90f3705
commit af5261d093
2 changed files with 22 additions and 9 deletions

View File

@@ -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<QString> 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);
}
}
}
}

View File

@@ -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}"));