diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index 83cce36fce..c8757e1252 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -61,6 +61,11 @@ namespace Volo.Abp.Cli.Commands ); } + if (!ProjectNameValidator.IsValid(projectName)) + { + throw new CliUsageException("The project name is invalid! Please specify a different name."); + } + Logger.LogInformation("Creating your project..."); Logger.LogInformation("Project name: " + projectName); @@ -554,4 +559,4 @@ namespace Volo.Abp.Cli.Commands } } } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs new file mode 100644 index 0000000000..daf13da410 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/ProjectNameValidator.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.Cli.Utils +{ + public static class ProjectNameValidator + { + private static readonly string[] IllegalProjectNames = new[] + { + "MyCompanyName.MyProjectName", + "MyProjectName", + "CON", //Windows doesn't accept these names as file name + "AUX", + "PRN", + "COM1", + "LPT2" + }; + + private static readonly char[] IllegalChars = new[] + { + '/', + '?', + ':', + '&', + '\\', + '*', + '\'', + '<', + '>', + '|', + '#', + '%', + }; + + private static bool HasParentDirectoryString(string projectName) + { + return projectName.Contains(".."); + } + + private static bool HasIllegalChar(string projectName) + { + foreach (var illegalWord in IllegalChars) + { + if (projectName.Contains(illegalWord)) + { + return false; + } + } + + return true; + } + + private static bool HasSurrogateOrControlChar(string projectName) + { + return projectName.Any(chr => char.IsControl(chr) || char.IsSurrogate(chr)); + } + + private static bool IsIllegalProjectName(string projectName) + { + foreach (var illegalProjectName in IllegalProjectNames) + { + if (projectName.Equals(illegalProjectName, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return true; + } + + public static bool IsValid(string projectName) + { + if (projectName == null) + { + throw new CliUsageException("Project name cannot be empty!"); + } + + if (HasIllegalChar(projectName)) + { + return false; + } + + if (HasSurrogateOrControlChar(projectName)) + { + return false; + } + + if (HasParentDirectoryString(projectName)) + { + return false; + } + + if (IsIllegalProjectName(projectName)) + { + return false; + } + + return true; + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectNameValidation_Tests.cs b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectNameValidation_Tests.cs new file mode 100644 index 0000000000..2e6d0074bd --- /dev/null +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectNameValidation_Tests.cs @@ -0,0 +1,75 @@ +using System.IO; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.Commands; +using Volo.Abp.Cli.ProjectModification; +using Xunit; + +namespace Volo.Abp.Cli +{ + public class ProjectNameValidation_Tests : AbpCliTestBase + { + private readonly NewCommand _newCommand; + + public ProjectNameValidation_Tests() + { + _newCommand = GetRequiredService(); + } + + [Fact] + public async Task IllegalProjectName_Test() + { + var illegalProjectNames = new[] + { + "MyCompanyName.MyProjectName", + "MyProjectName", + "CON", //Windows doesn't accept these names as file name + "AUX", + "PRN", + "COM1", + "LPT2" + }; + + foreach (var illegalProjectName in illegalProjectNames) + { + var args = new CommandLineArgs("new", illegalProjectName); + await _newCommand.ExecuteAsync(args).ShouldThrowAsync(); + } + } + + [Fact] + public async Task ContainsIllegalChar_Test() + { + var illegalChars = new[] + { + '/', + '?', + ':', + '&', + '\\', + '*', + '\'', + '<', + '>', + '|', + '#', + '%', + }; + + foreach (var illegalChar in illegalChars) + { + var args = new CommandLineArgs("new", "Test" + illegalChar); + await _newCommand.ExecuteAsync(args).ShouldThrowAsync(); + } + } + + [Fact] + public async Task ParentDirectoryContain_Test() + { + + var args = new CommandLineArgs("new", "Test..Test"); + await _newCommand.ExecuteAsync(args).ShouldThrowAsync(); + } + } +}