From 763630bca56099de4b38eb708c4edf66c4ef6d0f Mon Sep 17 00:00:00 2001 From: Ben McIlwain Date: Fri, 13 Feb 2026 14:20:34 -0500 Subject: [PATCH] Fix bug in updating registrar display name canonicalization (#2957) We have a restriction in our system that registrar display names be unique (as the display name is how registrars are queried through RDAP). And, the uniqueness constraint is enforced on the canonicalized version of the display name (with spaces and non alphanumeric characters removed). However, in the check enforcing this uniqueness, we were incorrectly checking against the existing saved entity of the same registrar, meaning that you couldn't update the display name of a single registrar to a new value that canonicalized the same (you would instead have to rename it to something else first that doesn't canonicalize the same, and then afterwards to the new desired value). That didn't make sense, so now we exclude the existing registrar entity from consideration when checking if there are conflicts. --- .../registry/tools/CreateOrUpdateRegistrarCommand.java | 5 ++++- .../google/registry/tools/UpdateRegistrarCommandTest.java | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java b/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java index b07f3ef17..469cd2c02 100644 --- a/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java +++ b/core/src/main/java/google/registry/tools/CreateOrUpdateRegistrarCommand.java @@ -400,7 +400,10 @@ abstract class CreateOrUpdateRegistrarCommand extends MutatingCommand { if (registrarName != null && !registrarName.equals(oldRegistrarName)) { String normalizedName = normalizeRegistrarName(registrarName); for (Registrar registrar : Registrar.loadAll()) { - if (registrar.getRegistrarName() != null) { + // Only check against other registrars (i.e. not the existing version of this one), and + // which also have a display name set. + if (!registrar.getRegistrarId().equals(clientId) + && registrar.getRegistrarName() != null) { checkArgument( !normalizedName.equals(normalizeRegistrarName(registrar.getRegistrarName())), "The registrar name %s normalizes identically to existing registrar name %s", diff --git a/core/src/test/java/google/registry/tools/UpdateRegistrarCommandTest.java b/core/src/test/java/google/registry/tools/UpdateRegistrarCommandTest.java index 796a356db..d1233d73e 100644 --- a/core/src/test/java/google/registry/tools/UpdateRegistrarCommandTest.java +++ b/core/src/test/java/google/registry/tools/UpdateRegistrarCommandTest.java @@ -968,6 +968,14 @@ class UpdateRegistrarCommandTest extends CommandTestCase () -> runCommand("--name tHeRe GiStRaR", "--force", "NewRegistrar")); } + @Test + void testSuccess_updateSameRegistrar_registrarNameSimilarToExisting() throws Exception { + // Note that "The -- registrar" normalizes identically to "The Registrar", which is created by + // JpaTransactionManagerExtension. + runCommand("--name The -- registrar", "--force", "TheRegistrar"); + assertThat(loadRegistrar("TheRegistrar").getRegistrarName()).isEqualTo("The -- registrar"); + } + @Test void testSuccess_poNumberNotSpecified_doesntWipeOutExisting() throws Exception { Registrar registrar =