diff --git a/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java b/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java index 5e241b4b09..7456a1232a 100644 --- a/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java @@ -35,8 +35,14 @@ package sonia.scm.util; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.base.Splitter; + import sonia.scm.Validateable; +//~--- JDK imports ------------------------------------------------------------ + +import java.util.regex.Pattern; + /** * * @author Sebastian Sdorra @@ -53,7 +59,7 @@ public class ValidationUtil /** Field description */ private static final String REGEX_REPOSITORYNAME = - "^[A-z0-9][A-z0-9\\.\\-_/]*$"; + "(?!^\\.\\.$)(?!^\\.$)(?!.*[\\\\\\[\\]])^[A-z0-9\\.][A-z0-9\\.\\-_/]*$"; /** Field description */ private static final String REGEX_USERNAME = @@ -141,9 +147,27 @@ public class ValidationUtil */ public static boolean isRepositoryNameValid(String name) { - return Util.isNotEmpty(name) && name.matches(REGEX_REPOSITORYNAME) - &&!name.contains("..") &&!name.endsWith("/.") &&!name.endsWith(".") - &&!name.endsWith("/") &&!name.contains("/./") &&!name.contains("//"); + Pattern pattern = Pattern.compile(REGEX_REPOSITORYNAME); + boolean result = true; + + if (Util.isNotEmpty(name)) + { + for (String p : Splitter.on('/').split(name)) + { + if (!pattern.matcher(p).matches()) + { + result = false; + + break; + } + } + } + else + { + result = false; + } + + return result; } /** diff --git a/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java b/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java index 388bb768bf..a6ce29241c 100644 --- a/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java +++ b/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java @@ -142,19 +142,92 @@ public class ValidationUtilTest assertTrue(ValidationUtil.isRepositoryNameValid("scm/plugins/git-plugin")); assertTrue(ValidationUtil.isRepositoryNameValid("s")); assertTrue(ValidationUtil.isRepositoryNameValid("sc")); + assertTrue(ValidationUtil.isRepositoryNameValid(".scm/plugins")); // issue 142 assertFalse(ValidationUtil.isRepositoryNameValid(".")); assertFalse(ValidationUtil.isRepositoryNameValid("/")); - assertFalse(ValidationUtil.isRepositoryNameValid(".scm/plugins")); assertFalse(ValidationUtil.isRepositoryNameValid("scm/plugins/.")); assertFalse(ValidationUtil.isRepositoryNameValid("scm/../plugins")); assertFalse(ValidationUtil.isRepositoryNameValid("scm/main/")); assertFalse(ValidationUtil.isRepositoryNameValid("/scm/main/")); - + // issue 144 assertFalse(ValidationUtil.isRepositoryNameValid("scm/./main")); assertFalse(ValidationUtil.isRepositoryNameValid("scm//main")); + + // issue 148 + //J- + String[] validPaths = { + "scm", + "scm/main", + "scm/plugins/git-plugin", + "s", + "sc", + ".scm/plugins", + ".hiddenrepo", + "b.", + "...", + "..c", + "d..", + "a/b..", + "a/..b", + "a..c", + }; + + String[] invalidPaths = { + ".", + "/", + "//", + "..", + "/.", + "/..", + "./", + "../", + "/../", + "/./", + "/...", + "/abc", + ".../", + "/sdf/", + "asdf/", + "./b", + "scm/plugins/.", + "scm/../plugins", + "scm/main/", + "/scm/main/", + "scm/./main", + "scm//main", + "scm\\main", + "scm/main-$HOME", + "scm/main-${HOME}-home", + "scm/main-%HOME-home", + "scm/main-%HOME%-home", + "abc$abc", + "abc%abc", + "abcabc", + "abc#abc", + "abc+abc", + "abc{abc", + "abc}abc", + "abc(abc", + "abc)abc", + "abc[abc", + "abc]abc", + "abc|abc" + }; + //J+ + + for (String path : validPaths) + { + assertTrue(ValidationUtil.isRepositoryNameValid(path)); + } + + for (String path : invalidPaths) + { + assertFalse(ValidationUtil.isRepositoryNameValid(path)); + } } /** diff --git a/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js b/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js index d3f4def73a..b5c8edb7c7 100644 --- a/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js +++ b/scm-webapp/src/main/webapp/resources/js/override/ext.form.vtypes.js @@ -51,15 +51,23 @@ Ext.apply(Ext.form.VTypes, { nameText: 'The name is invalid.', + repositoryNameRegex: /(?!^\.\.$)(?!^\.$)(?!.*[\[\]])^[A-z0-9\.][A-z0-9\.\-_/]*$/, + // repository name validator repositoryName: function(val){ - return /^[A-z0-9][A-z0-9\.\-_\/]*$/.test(val) - && ! val.contains('..') - && ! val.endsWith('/.') - && ! val.endsWith('/') - && ! val.endsWith('.') - && ! val.contains('/./') - && ! val.contains('//'); + var result = true; + if (val){ + var p = val.split('/'); + for (var i=0; i