GPG user ID matching: use case-insensitive matching
Although not mentioned in the GPG documentation at [1], GPG uses case-insensitive matching also for the '<' (exact e-mail) and '@' (partial e-mail) operators. Matching for '=' (full exact match) is case-sensitive. Compare [2]. [1] https://www.gnupg.org/documentation/manuals/gnupg/Specify-a-User-ID.html [2] https://dev.gnupg.org/source/gnupg/browse/master/g10/keyring.c;22f7dddc34446a8c3e9eddf6cb281f16802351d7$890 Bug: 547789 Change-Id: I2f5ab65807d5dde3aa00ff032894701bbd8418c9 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
616a7eeaec
commit
8caaaf956a
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019, Thomas Wolf <thomas.wolf@paranor.ch> and others
|
* Copyright (C) 2019, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials are made available under the
|
* This program and the accompanying materials are made available under the
|
||||||
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
||||||
|
@ -53,7 +53,7 @@ public void testFullEmail() throws Exception {
|
||||||
assertFalse(match(USER_ID, "<heinrichh>"));
|
assertFalse(match(USER_ID, "<heinrichh>"));
|
||||||
assertFalse(match(USER_ID, "<uni-duesseldorf>"));
|
assertFalse(match(USER_ID, "<uni-duesseldorf>"));
|
||||||
assertFalse(match(USER_ID, "<h@u>"));
|
assertFalse(match(USER_ID, "<h@u>"));
|
||||||
assertFalse(match(USER_ID, "<HeinrichH@uni-duesseldorf.de>"));
|
assertTrue(match(USER_ID, "<HeinrichH@uni-duesseldorf.de>"));
|
||||||
assertFalse(match(USER_ID.substring(0, USER_ID.length() - 1),
|
assertFalse(match(USER_ID.substring(0, USER_ID.length() - 1),
|
||||||
"<heinrichh@uni-duesseldorf.de>"));
|
"<heinrichh@uni-duesseldorf.de>"));
|
||||||
assertFalse(match("", "<>"));
|
assertFalse(match("", "<>"));
|
||||||
|
@ -72,8 +72,8 @@ public void testPartialEmail() throws Exception {
|
||||||
assertFalse(match(USER_ID, "@ "));
|
assertFalse(match(USER_ID, "@ "));
|
||||||
assertFalse(match(USER_ID, "@"));
|
assertFalse(match(USER_ID, "@"));
|
||||||
assertFalse(match(USER_ID, "@Heine"));
|
assertFalse(match(USER_ID, "@Heine"));
|
||||||
assertFalse(match(USER_ID, "@HeinrichH"));
|
assertTrue(match(USER_ID, "@HeinrichH"));
|
||||||
assertFalse(match(USER_ID, "@Heinrich"));
|
assertTrue(match(USER_ID, "@Heinrich"));
|
||||||
assertFalse(match("", "@"));
|
assertFalse(match("", "@"));
|
||||||
assertFalse(match("", "@h"));
|
assertFalse(match("", "@h"));
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ public void testSubstringAsterisk() throws Exception {
|
||||||
public void testExplicitFingerprint() throws Exception {
|
public void testExplicitFingerprint() throws Exception {
|
||||||
assertFalse(match("John Fade <j.fade@example.com>", "0xfade"));
|
assertFalse(match("John Fade <j.fade@example.com>", "0xfade"));
|
||||||
assertFalse(match("John Fade <0xfade@example.com>", "0xfade"));
|
assertFalse(match("John Fade <0xfade@example.com>", "0xfade"));
|
||||||
|
assertFalse(match("John Fade <0xfade@example.com>", "0xFADE"));
|
||||||
assertFalse(match("", "0xfade"));
|
assertFalse(match("", "0xfade"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ public void testZeroX() throws Exception {
|
||||||
assertTrue(match("John Fade <0xfade@example.com>", "*0xfade"));
|
assertTrue(match("John Fade <0xfade@example.com>", "*0xfade"));
|
||||||
assertTrue(match("John Fade <0xfade@example.com>", "*0xFADE"));
|
assertTrue(match("John Fade <0xfade@example.com>", "*0xFADE"));
|
||||||
assertTrue(match("John Fade <0xfade@example.com>", "@0xfade"));
|
assertTrue(match("John Fade <0xfade@example.com>", "@0xfade"));
|
||||||
assertFalse(match("John Fade <0xfade@example.com>", "@0xFADE"));
|
assertTrue(match("John Fade <0xfade@example.com>", "@0xFADE"));
|
||||||
assertFalse(match("", "0x"));
|
assertFalse(match("", "0x"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,23 +219,34 @@ static boolean containsSigningKey(String userId, String signingKeySpec) {
|
||||||
int stop = toMatch.indexOf('>');
|
int stop = toMatch.indexOf('>');
|
||||||
return begin >= 0 && end > begin + 1 && stop > 0
|
return begin >= 0 && end > begin + 1 && stop > 0
|
||||||
&& userId.substring(begin + 1, end)
|
&& userId.substring(begin + 1, end)
|
||||||
.equals(toMatch.substring(0, stop));
|
.equalsIgnoreCase(toMatch.substring(0, stop));
|
||||||
}
|
}
|
||||||
case '@': {
|
case '@': {
|
||||||
int begin = userId.indexOf('<');
|
int begin = userId.indexOf('<');
|
||||||
int end = userId.indexOf('>', begin + 1);
|
int end = userId.indexOf('>', begin + 1);
|
||||||
return begin >= 0 && end > begin + 1
|
return begin >= 0 && end > begin + 1
|
||||||
&& userId.substring(begin + 1, end).contains(toMatch);
|
&& containsIgnoreCase(userId.substring(begin + 1, end),
|
||||||
|
toMatch);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (toMatch.trim().isEmpty()) {
|
if (toMatch.trim().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return userId.toLowerCase(Locale.ROOT)
|
return containsIgnoreCase(userId, toMatch);
|
||||||
.contains(toMatch.toLowerCase(Locale.ROOT));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean containsIgnoreCase(String a, String b) {
|
||||||
|
int alength = a.length();
|
||||||
|
int blength = b.length();
|
||||||
|
for (int i = 0; i + blength <= alength; i++) {
|
||||||
|
if (a.regionMatches(true, i, b, 0, blength)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private String toFingerprint(String keyId) {
|
private String toFingerprint(String keyId) {
|
||||||
if (keyId.startsWith("0x")) { //$NON-NLS-1$
|
if (keyId.startsWith("0x")) { //$NON-NLS-1$
|
||||||
return keyId.substring(2);
|
return keyId.substring(2);
|
||||||
|
|
Loading…
Reference in New Issue