Verify the case of the project name before opening git repository
When a project is not in the project cache, Gerrit checks for the corresponding git repository in the file system and adds the project to the cache if the git repository is found. On Windows the paths are case-insensitive, which means that the lookup for the git repository in the file system is even successfull if the name of the project was given in an incorrect case. E.g. lets assume the project 'test/myProject' exists, then asking the project cache for 'test/myProject', 'TEST/myProject', 'test/MyProject' would all succeed. Even worse for each variant of the case a new instance of the project would be added to the cache. These instances of the same project in the project cache might even become inconsistent with each other. This problem is relevant for all SSH commands where the user can specify a project name, e.g. for 'set-project-parent'. If for the '--parent' parameter the project is specified in an incorrect case, this incorrect case is then even persisted in the 'project.config' file of the child projects. To avoid these problems, with this change the case of the project name is now verified and the project is only added to the cache if the project name was specified in the correct case. If the project name was specified in an incorrect case the lookup would fail with an RepositoryNotFoundException. Change-Id: Icf826d16e05a8c19537e86fe302b158bcb407bba Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||
import com.google.gerrit.server.git.ProjectConfig;
|
||||
import com.google.gerrit.server.git.ReplicationQueue;
|
||||
import com.google.gerrit.server.git.RepositoryCaseMismatchException;
|
||||
import com.google.gerrit.server.project.ProjectCache;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.sshd.BaseCommand;
|
||||
@@ -178,18 +179,9 @@ final class CreateProject extends BaseCommand {
|
||||
repo.close();
|
||||
}
|
||||
} catch (IllegalStateException err) {
|
||||
try {
|
||||
Repository repo = repoManager.openRepository(nameKey);
|
||||
try {
|
||||
if (repo.getObjectDatabase().exists()) {
|
||||
throw new UnloggedFailure(1, "fatal: project \"" + projectName + "\" exists");
|
||||
}
|
||||
} finally {
|
||||
repo.close();
|
||||
}
|
||||
} catch (RepositoryNotFoundException doesNotExist) {
|
||||
throw new Failure(1, "fatal: Cannot create " + projectName, err);
|
||||
}
|
||||
handleRepositoryExistsException(nameKey);
|
||||
} catch (RepositoryCaseMismatchException err) {
|
||||
handleRepositoryExistsException(err.getNameOfExistingProject());
|
||||
} catch (RepositoryNotFoundException badName) {
|
||||
throw new UnloggedFailure(1, "fatal: " + badName.getMessage());
|
||||
} catch (Exception err) {
|
||||
@@ -297,4 +289,21 @@ final class CreateProject extends BaseCommand {
|
||||
throw new Failure(1, "--branch \"" + branch + "\" is not a valid name");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRepositoryExistsException(final Project.NameKey projectName)
|
||||
throws Failure {
|
||||
try {
|
||||
Repository repo = repoManager.openRepository(projectName);
|
||||
try {
|
||||
if (repo.getObjectDatabase().exists()) {
|
||||
throw new UnloggedFailure(1, "fatal: project \"" + projectName
|
||||
+ "\" exists");
|
||||
}
|
||||
} finally {
|
||||
repo.close();
|
||||
}
|
||||
} catch (RepositoryNotFoundException err) {
|
||||
throw new Failure(1, "fatal: Cannot create " + projectName, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user