cli/config: check syntax of user configured field names

These restrictions are meant to prevent incompatibilities with the
Xapian query parser (which will split at non-word characters) and
clashes with future notmuch builtin fields.
This commit is contained in:
David Bremner 2019-03-27 07:13:31 -03:00
parent 7981bd050e
commit 4b9c03efc6
2 changed files with 70 additions and 1 deletions

View file

@ -24,6 +24,8 @@
#include <netdb.h> #include <netdb.h>
#include <assert.h> #include <assert.h>
#include "unicode-util.h"
static const char toplevel_config_comment[] = static const char toplevel_config_comment[] =
" .notmuch-config - Configuration file for the notmuch mail system\n" " .notmuch-config - Configuration file for the notmuch mail system\n"
"\n" "\n"
@ -790,6 +792,43 @@ _item_split (char *item, char **group, char **key)
return 0; return 0;
} }
/* These are more properly called Xapian fields, but the user facing
docs call them prefixes, so make the error message match */
static bool
validate_field_name (const char *str)
{
const char *key;
if (! g_utf8_validate (str, -1, NULL)) {
fprintf (stderr, "Invalid utf8: %s\n", str);
return false;
}
key = g_utf8_strrchr (str, -1, '.');
if (! key ) {
INTERNAL_ERROR ("Impossible code path on input: %s\n", str);
}
key++;
if (! *key) {
fprintf (stderr, "Empty prefix name: %s\n", str);
return false;
}
if (! unicode_word_utf8 (key)) {
fprintf (stderr, "Non-word character in prefix name: %s\n", key);
return false;
}
if (key[0] >= 'a' && key[0] <= 'z') {
fprintf (stderr, "Prefix names starting with lower case letters are reserved: %s\n", key);
return false;
}
return true;
}
#define BUILT_WITH_PREFIX "built_with." #define BUILT_WITH_PREFIX "built_with."
typedef struct config_key { typedef struct config_key {
@ -802,7 +841,7 @@ typedef struct config_key {
static struct config_key static struct config_key
config_key_table[] = { config_key_table[] = {
{"index.decrypt", true, false, NULL}, {"index.decrypt", true, false, NULL},
{"index.header.", true, true, NULL}, {"index.header.", true, true, validate_field_name},
{"query.", true, true, NULL}, {"query.", true, true, NULL},
}; };

View file

@ -15,6 +15,36 @@ notmuch search '*' | notmuch_search_sanitize > initial-threads
notmuch search --output=messages '*' > initial-message-ids notmuch search --output=messages '*' > initial-message-ids
notmuch dump > initial-dump notmuch dump > initial-dump
test_begin_subtest "adding illegal prefix name, bad utf8"
notmuch config set index.header.$'\xFF' "List-Id" 2>&1 | sed 's/:.*$//' >OUTPUT
cat <<EOF > EXPECTED
Invalid utf8
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "adding illegal prefix name, reserved for notmuch"
notmuch config set index.header.list "List-Id" 2>OUTPUT
cat <<EOF > EXPECTED
Prefix names starting with lower case letters are reserved: list
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "adding illegal prefix name, non-word character."
notmuch config set index.header.l:st "List-Id" 2>OUTPUT
cat <<EOF > EXPECTED
Non-word character in prefix name: l:st
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "adding empty prefix name."
notmuch config set index.header. "List-Id" 2>OUTPUT
Non-word character in prefix name: l:st
cat <<EOF > EXPECTED
Empty prefix name: index.header.
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "adding user header" test_begin_subtest "adding user header"
test_expect_code 0 "notmuch config set index.header.List \"List-Id\"" test_expect_code 0 "notmuch config set index.header.List \"List-Id\""