[PATCH v2 4/5] mailmap: use case-sensitive comparisons for local-parts and names

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



RFC 5321 is clear that the local-part of an email address (the part
before the at sign) is case sensitive, and this has been the case since
the original RFC 821.  It directs us that "the local-part MUST be
interpreted and assigned semantics only by the host specified in the
domain part of the address."

Since we are not that party, it's not correct for us to compare them
case insensitively.  However, we do still want to compare the domain
parts case insensitively, so let's add a helper that downcases the
domain and then compare byte by byte.

Similarly, it's not possible for us to correctly case-fold text in a
locale-insensitive way, so our handling of personal names has also been
subject to bugs.  Additionally, we've never handled non-ASCII characters
correctly, which means that our previous comparisons really only worked
well for a fraction of the people on the planet.  Since our code wasn't
right and it's basically impossible to compare personal names without
regard to case, let's also switch our matching of names to be byte by
byte.

Signed-off-by: brian m. carlson <sandals@xxxxxxxxxxxxxxxxxxxx>
---
 mailmap.c          | 27 ++++++++++++++++++++++++---
 t/t4203-mailmap.sh |  4 ++--
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/mailmap.c b/mailmap.c
index d3287b409a..5c52dbb7e0 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -64,7 +64,22 @@ static void free_mailmap_entry(void *p, const char *s)
  */
 static int namemap_cmp(const char *a, const char *b)
 {
-	return strcasecmp(a, b);
+	return strcmp(a, b);
+}
+
+/*
+ * Lowercases the domain (and only the domain) part of an email address.  The
+ * local-part, which is defined by RFC 5321 to be case sensitive, is not
+ * affected.
+ */
+static char *lowercase_email(char *s)
+{
+	char *end = strchrnul(s, '@');
+	while (*end) {
+		*end = tolower(*end);
+		end++;
+	}
+	return s;
 }
 
 static void add_mapping(struct string_list *map,
@@ -74,9 +89,13 @@ static void add_mapping(struct string_list *map,
 	struct mailmap_entry *me;
 	struct string_list_item *item;
 
+	lowercase_email(new_email);
+
 	if (old_email == NULL) {
 		old_email = new_email;
 		new_email = NULL;
+	} else {
+		lowercase_email(old_email);
 	}
 
 	item = string_list_insert(map, old_email);
@@ -300,7 +319,7 @@ static struct string_list_item *lookup_prefix(struct string_list *map,
 	 * real location of the key if one exists.
 	 */
 	while (0 <= --i && i < map->nr) {
-		int cmp = strncasecmp(map->items[i].string, string, len);
+		int cmp = strncmp(map->items[i].string, string, len);
 		if (cmp < 0)
 			/*
 			 * "i" points at a key definitely below the prefix;
@@ -323,6 +342,7 @@ int map_user(struct mailmap *map,
 	     const char **email, size_t *emaillen,
 	     const char **name, size_t *namelen)
 {
+	char *searchable_email = xstrndup(*email, *emaillen);
 	struct string_list_item *item;
 	struct mailmap_entry *me;
 
@@ -330,7 +350,8 @@ int map_user(struct mailmap *map,
 		 (int)*namelen, debug_str(*name),
 		 (int)*emaillen, debug_str(*email));
 
-	item = lookup_prefix(map->mailmap, *email, *emaillen);
+	item = lookup_prefix(map->mailmap, searchable_email, *emaillen);
+	free(searchable_email);
 	if (item != NULL) {
 		me = (struct mailmap_entry *)item->util;
 		if (me->namemap.nr) {
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 32e849504c..df4a0e03cc 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -187,7 +187,7 @@ nick1 (1):
 
 EOF
 
-test_expect_failure 'name entry after email entry, case-sensitive local-part' '
+test_expect_success 'name entry after email entry, case-sensitive local-part' '
 	mkdir -p internal_mailmap &&
 	echo "<bugs@xxxxxxxxxx> <bugs@xxxxxxxxxx>" >internal_mailmap/.mailmap &&
 	echo "Internal Guy <BUGS@xxxxxxxxxx>" >>internal_mailmap/.mailmap &&
@@ -195,7 +195,7 @@ test_expect_failure 'name entry after email entry, case-sensitive local-part' '
 	test_cmp expect actual
 '
 
-test_expect_failure 'name entry after email entry, case-sensitive personal name' '
+test_expect_success 'name entry after email entry, case-sensitive personal name' '
 	mkdir -p internal_mailmap &&
 	echo "<bugs@xxxxxxxxxx> <bugs@xxxxxxxxxx>" >internal_mailmap/.mailmap &&
 	echo "Nick1 <bugs@xxxxxxxxxx> NICK1 <bugs@xxxxxxxxxx>" >internal_mailmap/.mailmap &&



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux