Reject invalid Change-Id lines
EGit stores a placeholder "Change-Id: I0000..." line in the commit
message when first setting up a commit. If there is a bug in EGit it
might fail to replace this line, causing the user to upload a commit
to Gerrit with this placeholder Change-Id. Since the id is supposed to
be unique within a project, this upload will work at most once on a
server/project pair before it starts to cause problems for other users
on the same system. Check for this case and reject it when it occurs.
When creating a new change, validate that the selected Change-Id line
conforms to the I$commit_sha1 format that should be used. In the
several years that we have been using Change-Id lines, nobody has
found a reason to use a different line format unless they have a
broken client that has created an invalid line.
Change-Id: I64a46c0323b5e550e1415c8dfcf36ba2048820e1
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index b9045bc..ace7aee 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -913,6 +913,12 @@
final List<String> idList = c.getFooterLines(CHANGE_ID);
if (!idList.isEmpty()) {
final String idStr = idList.get(idList.size() - 1).trim();
+ if (idStr.matches("^I00*$")) {
+ // Reject this invalid line from EGit.
+ reject(newChange, "invalid Change-Id");
+ return;
+ }
+
final Change.Key key = new Change.Key(idStr);
if (newChangeIds.contains(key)) {
@@ -944,6 +950,11 @@
}
if (changes.size() == 0) {
+ if (!isValidChangeId(idStr)) {
+ reject(newChange, "invalid Change-Id");
+ return;
+ }
+
newChangeIds.add(key);
}
}
@@ -984,6 +995,10 @@
newChange.setResult(ReceiveCommand.Result.OK);
}
+ private static boolean isValidChangeId(String idStr) {
+ return idStr.matches("^I[0-9a-fA-F]{40}$") && !idStr.matches("^I00*$");
+ }
+
private void createChange(final RevWalk walk, final RevCommit c)
throws OrmException, IOException {
walk.parseBody(c);
@@ -998,7 +1013,7 @@
try {
if (footerLine.matches(CHANGE_ID)) {
final String v = footerLine.getValue().trim();
- if (v.matches("^I[0-9a-f]{8,}.*$")) {
+ if (isValidChangeId(v)) {
changeKey = new Change.Key(v);
}
} else if (isReviewer(footerLine)) {