diff options
| author | Anton Khirnov <anton@khirnov.net> | 2020-06-15 22:58:49 +0200 |
|---|---|---|
| committer | David Bremner <david@tethera.net> | 2020-06-16 08:02:02 -0300 |
| commit | 131757907907380213b32934d9e73cec942ace43 (patch) | |
| tree | 193d7bfa3977a7035993694aacb9c9b16933f2e6 /bindings/python-cffi/notmuch2/_database.py | |
| parent | 1bca41698a03980b701558fb5c481ef0a340460d (diff) | |
python/notmuch2: do not destroy messages owned by a query
Any messages retrieved from a query - either directly via
search_messages() or indirectly via thread objects - are owned by that
query. Retrieving the same message (i.e. corresponding to the same
message ID / database object) several times will always yield the same
C object.
The caller is allowed to destroy message objects owned by a query before
the query itself - which can save memory for long-lived queries.
However, that message must then never be retrieved again from that
query.
The python-notmuch2 bindings will currently destroy every message object
in Message._destroy(), which will lead to an invalid free if the same
message is then retrieved again. E.g. the following python program leads
to libtalloc abort()ing:
import notmuch2
db = notmuch2.Database(mode = notmuch2.Database.MODE.READ_ONLY)
t = next(db.threads('*'))
msgs = list(zip(t.toplevel(), t.toplevel()))
msgs = list(zip(t.toplevel(), t.toplevel()))
Fix this issue by creating a subclass of Message, which is used for
"standalone" message which have to be freed by the caller. Message class
is then used only for messages descended from a query, which do not need
to be freed by the caller.
Diffstat (limited to 'bindings/python-cffi/notmuch2/_database.py')
| -rw-r--r-- | bindings/python-cffi/notmuch2/_database.py | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/bindings/python-cffi/notmuch2/_database.py b/bindings/python-cffi/notmuch2/_database.py index 3c06402d..fc55fea8 100644 --- a/bindings/python-cffi/notmuch2/_database.py +++ b/bindings/python-cffi/notmuch2/_database.py @@ -400,7 +400,7 @@ class Database(base.NotmuchObject): capi.lib.NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID] if ret not in ok: raise errors.NotmuchError(ret) - msg = message.Message(self, msg_pp[0], db=self) + msg = message.StandaloneMessage(self, msg_pp[0], db=self) if sync_flags: msg.tags.from_maildir_flags() return self.AddedMessage( @@ -469,7 +469,7 @@ class Database(base.NotmuchObject): msg_p = msg_pp[0] if msg_p == capi.ffi.NULL: raise LookupError - msg = message.Message(self, msg_p, db=self) + msg = message.StandaloneMessage(self, msg_p, db=self) return msg def get(self, filename): @@ -502,7 +502,7 @@ class Database(base.NotmuchObject): msg_p = msg_pp[0] if msg_p == capi.ffi.NULL: raise LookupError - msg = message.Message(self, msg_p, db=self) + msg = message.StandaloneMessage(self, msg_p, db=self) return msg @property |
