From f48d2e2ff89a7e0a413b29ca844b2c785063eb3d Mon Sep 17 00:00:00 2001 From: David Bremner Date: Mon, 23 May 2022 20:38:55 -0300 Subject: [PATCH] lib/message: catch exceptions in _n_m_add_term Some code movement is needed to make sure the cache is only invalidated when the Xapian operation succeeds. --- lib/message.cc | 27 +++++++++++++++++---------- test/T566-lib-message.sh | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/message.cc b/lib/message.cc index 54609fcd..c331346f 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -1490,24 +1490,30 @@ _notmuch_message_add_term (notmuch_message_t *message, { char *term; + notmuch_private_status_t status = NOTMUCH_PRIVATE_STATUS_SUCCESS; if (value == NULL) return NOTMUCH_PRIVATE_STATUS_NULL_POINTER; term = talloc_asprintf (message, "%s%s", _find_prefix (prefix_name), value); + if (strlen (term) > NOTMUCH_TERM_MAX) { + status = NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG; + goto DONE; + } - if (strlen (term) > NOTMUCH_TERM_MAX) - return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG; - - message->doc.add_term (term, 0); - message->modified = true; + try { + message->doc.add_term (term, 0); + message->modified = true; + _notmuch_message_invalidate_metadata (message, prefix_name); + } catch (Xapian::Error &error) { + LOG_XAPIAN_EXCEPTION (message, error); + status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION; + } + DONE: talloc_free (term); - - _notmuch_message_invalidate_metadata (message, prefix_name); - - return NOTMUCH_PRIVATE_STATUS_SUCCESS; + return status; } /* Parse 'text' and add a term to 'message' for each parsed word. Each @@ -1571,11 +1577,12 @@ _notmuch_message_remove_term (notmuch_message_t *message, try { message->doc.remove_term (term); message->modified = true; - } catch (const Xapian::InvalidArgumentError) { + } catch (const Xapian::InvalidArgumentError &error) { /* We'll let the philosophers try to wrestle with the * question of whether failing to remove that which was not * there in the first place is failure. For us, we'll silently * consider it all good. */ + LOG_XAPIAN_EXCEPTION (message, error); } talloc_free (term); diff --git a/test/T566-lib-message.sh b/test/T566-lib-message.sh index b6a9e536..bc9bfcb6 100755 --- a/test/T566-lib-message.sh +++ b/test/T566-lib-message.sh @@ -307,6 +307,23 @@ cat < EXPECTED EOF test_expect_equal_file EXPECTED OUTPUT +test_begin_subtest "_notmuch_message_add_term catches exceptions" +cat c_head0 - c_tail <<'EOF' | test_private_C ${MAIL_DIR} + { + notmuch_private_status_t status; + /* This relies on Xapian throwing an exception for adding empty terms */ + status = _notmuch_message_add_term (message, "body", ""); + printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS ); + } +EOF +cat < EXPECTED +== stdout == +1 +1 +== stderr == +EOF +test_expect_equal_file EXPECTED OUTPUT + test_begin_subtest "Handle removing all tags with closed db" cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} {