From 6d87f55163859560a0c0c18f109d3d89ebf70d40 Mon Sep 17 00:00:00 2001 From: Aurelien Poscia Date: Mon, 14 Mar 2022 14:28:20 +0100 Subject: SONAR-14742 Project import from GitHub, Bitbucket and Azure can clash with existing project key --- .../org/sonar/core/component/ComponentKeys.java | 16 +++++- .../component/ComponentKeysSanitizationTest.java | 57 ++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 sonar-core/src/test/java/org/sonar/core/component/ComponentKeysSanitizationTest.java (limited to 'sonar-core') diff --git a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java index ab786773ea9..73dc84dacc7 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java +++ b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java @@ -34,11 +34,19 @@ public final class ComponentKeys { public static final String MALFORMED_KEY_MESSAGE = "Malformed key for '%s'. %s."; /** - * Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit + * Allowed characters are alphanumeric, '-', '_', '.' and ':' */ - private static final Pattern VALID_PROJECT_KEY_REGEXP = Pattern.compile("[\\p{Alnum}\\-_.:]*[\\p{Alpha}\\-_.:]+[\\p{Alnum}\\-_.:]*"); + private static final String VALID_PROJECT_KEY_CHARS = "\\p{Alnum}-_.:"; + + private static final Pattern INVALID_PROJECT_KEY_REGEXP = Pattern.compile("[^" + VALID_PROJECT_KEY_CHARS + "]"); + + /** + * At least one non-digit is necessary + */ + private static final Pattern VALID_PROJECT_KEY_REGEXP = Pattern.compile("[" + VALID_PROJECT_KEY_CHARS + "]*[\\p{Alpha}\\-_.:]+[" + VALID_PROJECT_KEY_CHARS + "]*"); private static final String KEY_WITH_BRANCH_FORMAT = "%s:%s"; + private static final String REPLACEMENT_CHARACTER = "_"; private ComponentKeys() { // only static stuff @@ -66,6 +74,10 @@ public final class ComponentKeys { checkArgument(isValidProjectKey(keyCandidate), MALFORMED_KEY_MESSAGE, keyCandidate, ALLOWED_CHARACTERS_MESSAGE); } + public static String sanitizeProjectKey(String rawProjectKey) { + return INVALID_PROJECT_KEY_REGEXP.matcher(rawProjectKey).replaceAll(REPLACEMENT_CHARACTER); + } + /** * Return the project key with potential branch */ diff --git a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysSanitizationTest.java b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysSanitizationTest.java new file mode 100644 index 00000000000..e8699f432ab --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysSanitizationTest.java @@ -0,0 +1,57 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.core.component; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(Parameterized.class) +public class ComponentKeysSanitizationTest { + + @Parameterized.Parameters(name = "{index}: input {0}, expected output {1}") + public static Collection data() { + return Arrays.asList(new String[][] { + {"/a/b/c/", "_a_b_c_"}, + {".a.b:c:", ".a.b:c:"}, + {"_1_2_3_", "_1_2_3_"}, + {"fully_valid_-name2", "fully_valid_-name2"}, + {"°+\"*ç%&\\/()=?`^“#Ç[]|{}≠¿ ~", "___________________________"}, + }); + } + + private final String inputString; + private final String expectedOutputString; + + public ComponentKeysSanitizationTest(String inputString, String expectedOutputString) { + this.inputString = inputString; + this.expectedOutputString = expectedOutputString; + } + + @Test + public void sanitizeProjectKey() { + assertThat(ComponentKeys.sanitizeProjectKey(inputString)).isEqualTo(expectedOutputString); + } + +} -- cgit v1.2.3