Skip to content

Commit

Permalink
Return None if deref encouters a broken reference (fixes #384) (#386
Browse files Browse the repository at this point in the history
)

* Return `None` if `deref` finds a broken reference

This commit introduces a check before a referenced entry is
resolved. If the referenced entry is not found `deref` will return
`None`. The commit also includes a test case for this behavior.

Fixes: #384

* update docstring

---------

Co-authored-by: evan <[email protected]>
  • Loading branch information
br-olf and Evidlo authored Apr 9, 2024
1 parent d08c275 commit 83440f4
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pykeepass/pykeepass.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ def deref(self, value):
ref (str): KeePass reference string to another field
Returns:
str or uuid.UUID
str, uuid.UUID or None if no match found
[fieldref]: https://keepass.info/help/base/fieldrefs.html
"""
Expand All @@ -710,6 +710,8 @@ def deref(self, value):
if search_in == 'uuid':
search_value = uuid.UUID(search_value)
ref_entry = self.find_entries(first=True, **{search_in: search_value})
if ref_entry is None:
return None
value = value.replace(ref, getattr(ref_entry, wanted_field))
return self.deref(value)

Expand Down
14 changes: 14 additions & 0 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,20 @@ def test_references(self):
self.assertNotEqual(original_entry, clone1)
self.assertNotEqual(clone1, clone2)

def test_broken_reference(self):
# TODO: move the entry into test databases
broken_entry_title = 'broken reference'
self.kp.add_entry(
self.kp.root_group,
title=broken_entry_title,
username='{REF:U@I:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}',
password='{REF:P@I:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}',
)
broken_entry = self.kp.find_entries(title=broken_entry_title, first=True)
self.assertEqual(broken_entry.deref('username'), None)
self.assertEqual(broken_entry.deref('password'), None)
self.kp.delete_entry(broken_entry)

def test_set_and_get_fields(self):
time = datetime.now(timezone.utc).replace(microsecond=0)
changed_time = time + timedelta(hours=9)
Expand Down

0 comments on commit 83440f4

Please sign in to comment.