command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

How to validate that an argument is a valid file path?

Open TPIvan opened this issue 3 years ago • 0 comments

I need an argument use for file creation or appending (path parameter in File.AppendAllText function). As far as I know there are two functions available LegalFileNamesOnly and LegalFilePathsOnly. The problem is that LegalFileNamesOnly validates just file name and so doesn't allow path characters like '\' or ':'. On the other hand LegalFilePathsOnly allows (as expected) path characters ( '', ':'), but also allows wildcard characters like '*' or '?', which cause the file writing function exception. Also there is not path length validation.

The problem is more serious when net framework 4.x is used. Because new FileInfo("C:\\*.txt"), which is legal in .net 6.0 causes an exception and so when the type of argument is FileInfo (like in Tutorial: Get started with System.CommandLine ) the exception will be in return await rootCommand.InvokeAsync(args); and so difficult to be reasonably handled.

Full example

internal class Program
{
    static async Task<int> Main(string[] args)
    {
        try
        {
            var fileOption = new Option<FileInfo>(
            name: "--file",
            description: "The file to read and display on the console.")
            { IsRequired = true };

            fileOption.LegalFilePathsOnly();

            var rootCommand = new RootCommand("Sample app for System.CommandLine");
            rootCommand.AddOption(fileOption);

            rootCommand.SetHandler((file) =>
            {
                WriteFile(file);
            },
                fileOption);

            return await rootCommand.InvokeAsync("--file C:\\test*.txt");
            //return await rootCommand.InvokeAsync("--file c:\\temp\\testForentitiesbeingtrackedbytheDbContextthevaluesofforeignkeypropertiesindependententitiesarenotchangedwhentherelatedprincipalentityisdeletedThiscanresultinaninconsistentgraphofentitieswherethevaluesofforeignkeypropertiesdonotmatchtherelationshipsinthegraph.txt");


        }
        finally
        {
            Console.ReadLine();
        }

    }

    static void WriteFile(FileInfo file)
    {
        System.IO.File.AppendAllText(file.FullName, "testing text " + DateTime.Now.ToString() + "\n");
    }
}

When running on .net 6.0 it fails on System.IO.File.AppendAllText.... and on framework 4.7.2 it fails on return await rootCommand... in both case with System.ArgumentException: Illegal characters in path.

When the too long filename is used (the commented out line) we get "System.IO.IOException: 'The filename, directory name, or volume label syntax is incorrect. " on net 6.0 and on framework "System.IO.PathTooLongException" on the same lines.

TPIvan avatar Sep 01 '22 11:09 TPIvan