Honor alternate autofill targets from entry fields
This commit is contained in:
@@ -42,11 +42,11 @@ final class AutofillCacheStore {
|
||||
List<Entry> exactHost = new ArrayList<>();
|
||||
List<Entry> parentHost = new ArrayList<>();
|
||||
for (Entry entry : entries) {
|
||||
if (entry.host.equals(target.host)) {
|
||||
if (entryMatchesHost(entry, target.host)) {
|
||||
exactHost.add(entry);
|
||||
continue;
|
||||
}
|
||||
if (!entry.host.isEmpty() && target.host.endsWith("." + entry.host)) {
|
||||
if (entryMatchesParentHost(entry, target.host)) {
|
||||
parentHost.add(entry);
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,7 @@ final class AutofillCacheStore {
|
||||
String password = "";
|
||||
String host = "";
|
||||
String url = "";
|
||||
List<String> targets = new ArrayList<>();
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String name = reader.nextName();
|
||||
@@ -127,13 +128,20 @@ final class AutofillCacheStore {
|
||||
case "host":
|
||||
host = normalizeHost(nextString(reader));
|
||||
break;
|
||||
case "targets":
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
targets.add(nextString(reader));
|
||||
}
|
||||
reader.endArray();
|
||||
break;
|
||||
default:
|
||||
reader.skipValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.endObject();
|
||||
return new Entry(title, username, password, host, url);
|
||||
return new Entry(title, username, password, host, url, targets);
|
||||
}
|
||||
|
||||
private static String nextString(JsonReader reader) throws IOException {
|
||||
@@ -209,16 +217,21 @@ final class AutofillCacheStore {
|
||||
|
||||
List<Entry> exact = new ArrayList<>();
|
||||
List<Entry> prefix = new ArrayList<>();
|
||||
int bestPrefixLen = -1;
|
||||
for (Entry entry : entries) {
|
||||
NormalizedTarget entryTarget = normalizeURL(entry.url);
|
||||
if (entryTarget.host.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (entryTarget.url.equals(target.url)) {
|
||||
MatchQuality quality = bestTargetMatch(entry, target);
|
||||
if (quality.exact) {
|
||||
exact.add(entry);
|
||||
continue;
|
||||
}
|
||||
if (!"/".equals(entryTarget.path) && target.path.startsWith(entryTarget.path)) {
|
||||
if (quality.prefixLength <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (quality.prefixLength > bestPrefixLen) {
|
||||
prefix.clear();
|
||||
prefix.add(entry);
|
||||
bestPrefixLen = quality.prefixLength;
|
||||
} else if (quality.prefixLength == bestPrefixLen) {
|
||||
prefix.add(entry);
|
||||
}
|
||||
}
|
||||
@@ -229,23 +242,54 @@ final class AutofillCacheStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
Entry best = null;
|
||||
int bestLen = -1;
|
||||
boolean ambiguous = false;
|
||||
for (Entry entry : prefix) {
|
||||
int pathLen = normalizeURL(entry.url).path.length();
|
||||
if (pathLen > bestLen) {
|
||||
best = entry;
|
||||
bestLen = pathLen;
|
||||
ambiguous = false;
|
||||
} else if (pathLen == bestLen) {
|
||||
ambiguous = true;
|
||||
return prefix.size() == 1 ? prefix.get(0) : null;
|
||||
}
|
||||
|
||||
private static boolean entryMatchesHost(Entry entry, String host) {
|
||||
for (NormalizedTarget target : entryTargets(entry)) {
|
||||
if (target.host.equals(host)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ambiguous) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean entryMatchesParentHost(Entry entry, String host) {
|
||||
for (NormalizedTarget target : entryTargets(entry)) {
|
||||
if (!target.host.isEmpty() && host.endsWith("." + target.host)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<NormalizedTarget> entryTargets(Entry entry) {
|
||||
List<String> rawTargets = entry.targets;
|
||||
if (rawTargets.isEmpty()) {
|
||||
rawTargets = new ArrayList<>();
|
||||
rawTargets.add(entry.url);
|
||||
}
|
||||
List<NormalizedTarget> targets = new ArrayList<>();
|
||||
for (String rawTarget : rawTargets) {
|
||||
NormalizedTarget target = normalizeURL(rawTarget);
|
||||
if (!target.host.isEmpty()) {
|
||||
targets.add(target);
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
private static MatchQuality bestTargetMatch(Entry entry, NormalizedTarget target) {
|
||||
int bestPrefixLen = -1;
|
||||
for (NormalizedTarget entryTarget : entryTargets(entry)) {
|
||||
if (entryTarget.url.equals(target.url)) {
|
||||
return new MatchQuality(true, 0);
|
||||
}
|
||||
if (!"/".equals(entryTarget.path) && target.path.startsWith(entryTarget.path)) {
|
||||
bestPrefixLen = Math.max(bestPrefixLen, entryTarget.path.length());
|
||||
}
|
||||
}
|
||||
return new MatchQuality(false, bestPrefixLen);
|
||||
}
|
||||
|
||||
static final class Entry {
|
||||
@@ -254,13 +298,25 @@ final class AutofillCacheStore {
|
||||
final String password;
|
||||
final String host;
|
||||
final String url;
|
||||
final List<String> targets;
|
||||
|
||||
Entry(String title, String username, String password, String host, String url) {
|
||||
Entry(String title, String username, String password, String host, String url, List<String> targets) {
|
||||
this.title = title;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.host = host;
|
||||
this.url = url;
|
||||
this.targets = new ArrayList<>(targets);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MatchQuality {
|
||||
final boolean exact;
|
||||
final int prefixLength;
|
||||
|
||||
MatchQuality(boolean exact, int prefixLength) {
|
||||
this.exact = exact;
|
||||
this.prefixLength = prefixLength;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user