[PATCH] implement search --format=sanitized_text + emacs UI to use it

Subject: [PATCH] implement search --format=sanitized_text + emacs UI to use it

Date: Sat, 7 May 2011 01:17:26 +0200

To: notmuch@notmuchmail.org

Cc: a.amann@ucc.ie

From: Florian Friesdorf


Sanitize "Subject:" and "Author:" fields to not contain control
characters for sanitized_text format.

When a Subject field contains encoded CRLF sequences, these sequences
would appear unfiltered in the output of notmuch search. This confused
the notmuch emacs interface leading to "Unexpected Output"
messages. This is now fixed by replacing all characters with ASCII
code less than 32 with a question mark for the sanitized_text
format. The emacs UI uses this format.

Thank you to Andreas Amann <a.amann@ucc.ie>, who wrote the initial
patch, I just turned it into a new format.

missing:
- man page update
- test, (works for me)
- investigate initialization warning:
CC -O2 notmuch-search.o
notmuch-search.c:98:1: warning: missing initializer
notmuch-search.c:98:1: warning: (near initialization for
'format_sanitized_text.results_null')
---
 emacs/notmuch.el |    3 +-
 notmuch-search.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 1d683f8..9d7c212 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -879,7 +879,8 @@ The optional parameters are used as follows:
 		     (if oldest-first
 			 "--sort=oldest-first"
 		       "--sort=newest-first")
-		     query)))
+                     "--format=sanitized_text"
+                     query)))
 	  (set-process-sentinel proc 'notmuch-search-process-sentinel)
 	  (set-process-filter proc 'notmuch-search-process-filter))))
     (run-hooks 'notmuch-search-hook)))
diff --git a/notmuch-search.c b/notmuch-search.c
index 5e39511..d59dc44 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -78,6 +78,26 @@ static const search_format_t format_text = {
 };
 
 static void
+format_thread_sanitized_text (const void *ctx,
+			      const char *thread_id,
+			      const time_t date,
+			      const int matched,
+			      const int total,
+			      const char *authors,
+			      const char *subject);
+static const search_format_t format_sanitized_text = {
+    "",
+	"",
+	    format_item_id_text,
+	    format_thread_sanitized_text,
+	    " (",
+		"%s", " ",
+	    ")", "\n",
+	"",
+    "",
+};
+
+static void
 format_item_id_json (const void *ctx,
 		     const char *item_type,
 		     const char *item_id);
@@ -129,6 +149,42 @@ format_thread_text (const void *ctx,
 	    subject);
 }
 
+static char *
+sanitize_string(const void *ctx, const char *str)
+{
+    char *out, *loop;
+
+    loop = out = talloc_strdup (ctx, str);
+
+    for(;*loop;loop++){
+	if ((unsigned char)(*loop) < 32)
+	    *loop = '?';
+    }
+    return out;
+}
+
+static void
+format_thread_sanitized_text (const void *ctx,
+			      const char *thread_id,
+			      const time_t date,
+			      const int matched,
+			      const int total,
+			      const char *authors,
+			      const char *subject)
+{
+    void *ctx_quote = talloc_new (ctx);
+
+    printf ("thread:%s %12s [%d/%d] %s; %s",
+	    thread_id,
+	    notmuch_time_relative_date (ctx, date),
+	    matched,
+	    total,
+	    sanitize_string(ctx_quote, authors),
+	    sanitize_string(ctx_quote, subject));
+
+    talloc_free (ctx_quote);
+}
+
 static void
 format_item_id_json (const void *ctx,
 		     unused (const char *item_type),
@@ -378,6 +434,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[])
 	    opt = argv[i] + sizeof ("--format=") - 1;
 	    if (strcmp (opt, "text") == 0) {
 		format = &format_text;
+	    } else if (strcmp (opt, "sanitized_text") == 0) {
+		format = &format_sanitized_text;
 	    } else if (strcmp (opt, "json") == 0) {
 		format = &format_json;
 	    } else {
-- 
1.7.5.1


Thread: