From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 104AF6DE0A9A for ; Thu, 30 Aug 2018 04:30:05 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: 0.001 X-Spam-Level: X-Spam-Status: No, score=0.001 tagged_above=-999 required=5 tests=[AWL=0.012, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7vaPzo_zAobG for ; Thu, 30 Aug 2018 04:30:04 -0700 (PDT) Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) by arlo.cworth.org (Postfix) with ESMTPS id E17566DE0931 for ; Thu, 30 Aug 2018 04:29:50 -0700 (PDT) Received: from remotemail by fethera.tethera.net with local (Exim 4.89) (envelope-from ) id 1fvL93-0007HR-UJ; Thu, 30 Aug 2018 07:29:49 -0400 Received: (nullmailer pid 12143 invoked by uid 1000); Thu, 30 Aug 2018 11:29:32 -0000 From: David Bremner To: notmuch@notmuchmail.org Subject: [PATCH 14/15] lib: add _notmuch_message_id_parse_strict Date: Thu, 30 Aug 2018 08:29:14 -0300 Message-Id: <20180830112915.11761-15-david@tethera.net> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180830112915.11761-1-david@tethera.net> References: <20180830112915.11761-1-david@tethera.net> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Aug 2018 11:30:05 -0000 The idea is that if a message-id parses with this function, the MUA generating it was probably sane, and in particular it's probably safe to use the result as a parent from In-Reply-to. --- lib/message-id.c | 32 ++++++++++++++++++ lib/notmuch-private.h | 14 ++++++++ test/Makefile.local | 6 +++- test/T710-message-id.sh | 73 +++++++++++++++++++++++++++++++++++++++++ test/message-id-parse.c | 26 +++++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100755 test/T710-message-id.sh create mode 100644 test/message-id-parse.c diff --git a/lib/message-id.c b/lib/message-id.c index d7541d50..a1dce9c8 100644 --- a/lib/message-id.c +++ b/lib/message-id.c @@ -1,4 +1,5 @@ #include "notmuch-private.h" +#include "string-util.h" /* Advance 'str' past any whitespace or RFC 822 comments. A comment is * a (potentially nested) parenthesized sequence with '\' used to @@ -94,3 +95,34 @@ _notmuch_message_id_parse (void *ctx, const char *message_id, const char **next) return result; } + +char * +_notmuch_message_id_parse_strict (void *ctx, const char *message_id) +{ + const char *s, *end; + char *result; + + if (message_id == NULL || *message_id == '\0') + return NULL; + + s = skip_space (message_id); + if (*s == '<') + s++; + else + return NULL; + + for (end = s; *end && *end != '>'; end++) + if (isspace (*end)) + return NULL; + + if (*end != '>') + return NULL; + else { + const char *last = skip_space (end+1); + if (*last != '\0') + return NULL; + } + + result = talloc_strndup (ctx, s, end - s); + return result; +} diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index fd0d251b..5bbaa292 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -526,6 +526,20 @@ _notmuch_query_count_documents (notmuch_query_t *query, char * _notmuch_message_id_parse (void *ctx, const char *message_id, const char **next); +/* Parse a message-id, discarding leading and trailing whitespace, and + * '<' and '>' delimiters. + * + * Apply a probably-stricter-than RFC definition of what is allowed in + * a message-id. In particular, forbid whitespace. + * + * Returns a newly talloc'ed string belonging to 'ctx'. + * + * Returns NULL if there is any error parsing the message-id. + */ + +char * +_notmuch_message_id_parse_strict (void *ctx, const char *message_id); + /* message.cc */ diff --git a/test/Makefile.local b/test/Makefile.local index 1a0ab813..1cf09778 100644 --- a/test/Makefile.local +++ b/test/Makefile.local @@ -15,6 +15,9 @@ smtp_dummy_modules = $(smtp_dummy_srcs:.c=.o) $(dir)/arg-test: $(dir)/arg-test.o command-line-arguments.o util/libnotmuch_util.a $(call quiet,CC) $^ -o $@ $(LDFLAGS) +$(dir)/message-id-parse: $(dir)/message-id-parse.o lib/libnotmuch.a util/libnotmuch_util.a + $(call quiet,CC) $^ -o $@ $(LDFLAGS) $(TALLOC_LDFLAGS) + $(dir)/hex-xcode: $(dir)/hex-xcode.o command-line-arguments.o util/libnotmuch_util.a $(call quiet,CC) $^ -o $@ $(LDFLAGS) $(TALLOC_LDFLAGS) @@ -50,7 +53,8 @@ test_main_srcs=$(dir)/arg-test.c \ $(dir)/smtp-dummy.c \ $(dir)/symbol-test.cc \ $(dir)/make-db-version.cc \ - $(dir)/ghost-report.cc + $(dir)/ghost-report.cc \ + $(dir)/message-id-parse.c test_srcs=$(test_main_srcs) $(dir)/database-test.c diff --git a/test/T710-message-id.sh b/test/T710-message-id.sh new file mode 100755 index 00000000..e73d6ba9 --- /dev/null +++ b/test/T710-message-id.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +test_description="message id parsing" + +. $(dirname "$0")/test-lib.sh || exit 1 + +test_begin_subtest "good message ids" +${TEST_DIRECTORY}/message-id-parse <OUTPUT +<018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915.git.jani@nikula.org> +<1530507300.raoomurnbf.astroid@strange.none> +<1258787708-21121-2-git-send-email-keithp@keithp.com> +EOF +cat <EXPECTED +GOOD: 018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915.git.jani@nikula.org +GOOD: 1530507300.raoomurnbf.astroid@strange.none +GOOD: 1258787708-21121-2-git-send-email-keithp@keithp.com +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "leading and trailing space is OK" +${TEST_DIRECTORY}/message-id-parse <OUTPUT + <018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915.git.jani@nikula.org> +<1530507300.raoomurnbf.astroid@strange.none> + <1258787708-21121-2-git-send-email-keithp@keithp.com> +EOF +cat <EXPECTED +GOOD: 018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915.git.jani@nikula.org +GOOD: 1530507300.raoomurnbf.astroid@strange.none +GOOD: 1258787708-21121-2-git-send-email-keithp@keithp.com +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "<> delimeters are required" +${TEST_DIRECTORY}/message-id-parse <OUTPUT +018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915.git.jani@nikula.org> +<1530507300.raoomurnbf.astroid@strange.none +1258787708-21121-2-git-send-email-keithp@keithp.com +EOF +cat <EXPECTED +BAD: 018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915.git.jani@nikula.org> +BAD: <1530507300.raoomurnbf.astroid@strange.none +BAD: 1258787708-21121-2-git-send-email-keithp@keithp.com +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "embedded whitespace is forbidden" +${TEST_DIRECTORY}/message-id-parse <OUTPUT +<018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915 .git.jani@nikula.org> +<1530507300.raoomurnbf.astroid @strange.none> +<1258787708-21121- 2-git-send-email-keithp@keithp.com> +EOF +cat <EXPECTED +BAD: <018b1a8f2d1df62e804ce88b65401304832dfbbf.1346614915 .git.jani@nikula.org> +BAD: <1530507300.raoomurnbf.astroid @strange.none> +BAD: <1258787708-21121- 2-git-send-email-keithp@keithp.com> +EOF +test_expect_equal_file EXPECTED OUTPUT + + +test_begin_subtest "folded real life bad In-Reply-To values" +${TEST_DIRECTORY}/message-id-parse <OUTPUT +<22597.31869.380767.339702@chiark.greenend.org.uk> (Ian Jackson's message of "Mon, 5 Dec 2016 14:41:01 +0000") +<20170625141242.loaalhis2eodo66n@gaara.hadrons.org> <149719990964.27883.13021127452105787770.reportbug@seneca.home.org> +Your message of Tue, 09 Dec 2014 13:21:11 +0100. <1900758.CgLNVPbY9N@liber> +EOF +cat <EXPECTED +BAD: <22597.31869.380767.339702@chiark.greenend.org.uk> (Ian Jackson's message of "Mon, 5 Dec 2016 14:41:01 +0000") +BAD: <20170625141242.loaalhis2eodo66n@gaara.hadrons.org> <149719990964.27883.13021127452105787770.reportbug@seneca.home.org> +BAD: Your message of Tue, 09 Dec 2014 13:21:11 +0100. <1900758.CgLNVPbY9N@liber> +EOF +test_expect_equal_file EXPECTED OUTPUT + + +test_done diff --git a/test/message-id-parse.c b/test/message-id-parse.c new file mode 100644 index 00000000..752eb1fd --- /dev/null +++ b/test/message-id-parse.c @@ -0,0 +1,26 @@ +#include +#include +#include "notmuch-private.h" + +int +main (unused (int argc), unused (char **argv)) +{ + char *line = NULL; + size_t len = 0; + ssize_t nread; + void *local = talloc_new (NULL); + + while ((nread = getline (&line, &len, stdin)) != -1) { + int last = strlen (line) - 1; + if (line[last] == '\n') + line[last] = '\0'; + + char *mid = _notmuch_message_id_parse_strict (local, line); + if (mid) + printf ("GOOD: %s\n", mid); + else + printf ("BAD: %s\n", line); + } + + talloc_free (local); +} -- 2.18.0