ChangeField: Ignore invalid reviewer field values and log an error

We didn't see any failures with this, but it's better to be able to
handle invalid data from the index.

Change-Id: I958ec9851337d9f76349e81c04ee2358a738dde5
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2018-02-02 14:20:51 +01:00
parent a7c80b0003
commit 19d1baaa4f

View File

@@ -27,6 +27,8 @@ import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet; import static java.util.stream.Collectors.toSet;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Enums;
import com.google.common.base.Optional;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@@ -34,6 +36,7 @@ import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Table; import com.google.common.collect.Table;
import com.google.common.primitives.Longs;
import com.google.gerrit.common.data.SubmitRecord; import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.index.FieldDef; import com.google.gerrit.index.FieldDef;
import com.google.gerrit.index.SchemaUtil; import com.google.gerrit.index.SchemaUtil;
@@ -78,6 +81,8 @@ import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Fields indexed on change documents. * Fields indexed on change documents.
@@ -90,6 +95,8 @@ import org.eclipse.jgit.lib.PersonIdent;
* unambiguous derived field names containing other characters. * unambiguous derived field names containing other characters.
*/ */
public class ChangeField { public class ChangeField {
private static final Logger log = LoggerFactory.getLogger(ChangeField.class);
public static final int NO_ASSIGNEE = -1; public static final int NO_ASSIGNEE = -1;
private static final Gson GSON = OutputFormat.JSON_COMPACT.newGson(); private static final Gson GSON = OutputFormat.JSON_COMPACT.newGson();
@@ -253,18 +260,40 @@ public class ChangeField {
ImmutableTable.Builder<ReviewerStateInternal, Account.Id, Timestamp> b = ImmutableTable.Builder<ReviewerStateInternal, Account.Id, Timestamp> b =
ImmutableTable.builder(); ImmutableTable.builder();
for (String v : values) { for (String v : values) {
int f = v.indexOf(',');
if (f < 0) { int i = v.indexOf(',');
if (i < 0) {
log.error("Invalid value for reviewer field: %s", v);
continue; continue;
} }
int l = v.lastIndexOf(',');
if (l == f) { int i2 = v.lastIndexOf(',');
if (i2 == i) {
log.error("Invalid value for reviewer field: %s", v);
continue; continue;
} }
b.put(
ReviewerStateInternal.valueOf(v.substring(0, f)), Optional<ReviewerStateInternal> reviewerState =
Account.Id.parse(v.substring(f + 1, l)), Enums.getIfPresent(ReviewerStateInternal.class, v.substring(0, i));
new Timestamp(Long.valueOf(v.substring(l + 1, v.length())))); if (!reviewerState.isPresent()) {
log.error("Failed to parse reviewer state from reviewer field: %s", v);
continue;
}
Account.Id accountId = Account.Id.parse(v.substring(i + 1, i2));
if (accountId == null) {
log.error("Failed to parse account ID from reviewer field: %s", v);
continue;
}
Long l = Longs.tryParse(v.substring(i2 + 1, v.length()));
if (l == null) {
log.error("Failed to parse timestamp from reviewer field: %s", v);
continue;
}
Timestamp timestamp = new Timestamp(l);
b.put(reviewerState.get(), accountId, timestamp);
} }
return ReviewerSet.fromTable(b.build()); return ReviewerSet.fromTable(b.build());
} }
@@ -272,18 +301,39 @@ public class ChangeField {
public static ReviewerByEmailSet parseReviewerByEmailFieldValues(Iterable<String> values) { public static ReviewerByEmailSet parseReviewerByEmailFieldValues(Iterable<String> values) {
ImmutableTable.Builder<ReviewerStateInternal, Address, Timestamp> b = ImmutableTable.builder(); ImmutableTable.Builder<ReviewerStateInternal, Address, Timestamp> b = ImmutableTable.builder();
for (String v : values) { for (String v : values) {
int f = v.indexOf(','); int i = v.indexOf(',');
if (f < 0) { if (i < 0) {
log.error("Invalid value for reviewer by email field: %s", v);
continue; continue;
} }
int l = v.lastIndexOf(',');
if (l == f) { int i2 = v.lastIndexOf(',');
if (i2 == i) {
log.error("Invalid value for reviewer by email field: %s", v);
continue; continue;
} }
b.put(
ReviewerStateInternal.valueOf(v.substring(0, f)), Optional<ReviewerStateInternal> reviewerState =
Address.parse(v.substring(f + 1, l)), Enums.getIfPresent(ReviewerStateInternal.class, v.substring(0, i));
new Timestamp(Long.valueOf(v.substring(l + 1, v.length())))); if (!reviewerState.isPresent()) {
log.error("Failed to parse reviewer state from reviewer by email field: %s", v);
continue;
}
Address address = Address.tryParse(v.substring(i + 1, i2));
if (address == null) {
log.error("Failed to parse address from reviewer by email field: %s", v);
continue;
}
Long l = Longs.tryParse(v.substring(i2 + 1, v.length()));
if (l == null) {
log.error("Failed to parse timestamp from reviewer by email field: %s", v);
continue;
}
Timestamp timestamp = new Timestamp(l);
b.put(reviewerState.get(), address, timestamp);
} }
return ReviewerByEmailSet.fromTable(b.build()); return ReviewerByEmailSet.fromTable(b.build());
} }