Skip to content

Commit

Permalink
Merge pull request #556 from WildernessLabs/file_path_fixes
Browse files Browse the repository at this point in the history
Fix file and folder sanitization for file-related commands
  • Loading branch information
ctacke authored Apr 30, 2024
2 parents f3a2476 + 24424b0 commit 39ce3f7
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 39 deletions.
32 changes: 20 additions & 12 deletions Source/v2/Meadow.CLI/Commands/Current/App/AppTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,34 @@ internal static async Task<bool> TrimApplication(string path,
return true;
}

internal static string SanitiseMeadowFilename(string fileName)
internal static string SanitizeMeadowFolderName(string fileName)
{
return SanitizeMeadowFilename(fileName) + '/';
}

internal static string SanitizeMeadowFilename(string fileName)
{
fileName = fileName.Replace('\\', Path.DirectorySeparatorChar);
fileName = fileName.Replace('/', Path.DirectorySeparatorChar);

var folder = Path.GetDirectoryName(fileName);

if (string.IsNullOrWhiteSpace(folder))
{
folder = MeadowRootFolder;
folder = Path.DirectorySeparatorChar + MeadowRootFolder;
}
else
{
if (folder.EndsWith('/') == false)
{
folder += "/";
}
if (folder.StartsWith('/') == false)
{
folder = $"/{folder}";
}
if (folder.Contains(MeadowRootFolder) == false)
if (!folder.StartsWith(Path.DirectorySeparatorChar))
{
folder = $"/{MeadowRootFolder}{folder}";
if (!folder.StartsWith($"{MeadowRootFolder}"))
{
folder = $"{Path.DirectorySeparatorChar}{MeadowRootFolder}{Path.DirectorySeparatorChar}{folder}";
}
else
{
folder = $"{Path.DirectorySeparatorChar}{folder}";
}
}
}

Expand Down
27 changes: 9 additions & 18 deletions Source/v2/Meadow.Cli/Commands/Current/File/FileDeleteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ protected override async ValueTask ExecuteCommand()
await device.RuntimeDisable(CancellationToken);
}

// get a list of files in the target folder
var folder = Path.GetDirectoryName(MeadowFile)!.Replace(Path.DirectorySeparatorChar, '/');
if (string.IsNullOrWhiteSpace(folder))
{
folder = $"/{AppTools.MeadowRootFolder}/";
}
Logger?.LogInformation($"Looking for file {MeadowFile}...");

var folder = AppTools.SanitizeMeadowFolderName(Path.GetDirectoryName(MeadowFile)!);

var fileList = await connection.GetFileList($"{folder}", false, CancellationToken);

Expand All @@ -55,29 +52,23 @@ protected override async ValueTask ExecuteCommand()

var exists = fileList?.Any(f => Path.GetFileName(f.Name) == requested) ?? false;

var file = AppTools.SanitizeMeadowFilename(MeadowFile);

if (!exists)
{
Logger?.LogError($"File '{MeadowFile}' not found on device.");
Logger?.LogError($"File '{file}' not found on device");
}
else
{
var wasRuntimeEnabled = await device.IsRuntimeEnabled(CancellationToken);

if (wasRuntimeEnabled)
{
Logger?.LogError($"The runtime must be disabled before doing any file management. Use 'meadow runtime disable' first.");
return;
}

Logger?.LogInformation($"Deleting file '{MeadowFile}' from device...");
await device.DeleteFile(AppTools.SanitiseMeadowFilename(MeadowFile), CancellationToken);
Logger?.LogInformation($"Deleting file '{file}' from device...");
await device.DeleteFile(file, CancellationToken);
}
}
}

private async Task DeleteFileRecursive(IMeadowDevice device, string directoryname, MeadowFileInfo fileInfo, CancellationToken cancellationToken)
{
var meadowFile = AppTools.SanitiseMeadowFilename(Path.Combine(directoryname, fileInfo.Name));
var meadowFile = AppTools.SanitizeMeadowFilename(Path.Combine(directoryname, fileInfo.Name));
if (fileInfo.IsDirectory)
{
// Add a backslash as we're a directory and not a file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ protected override async ValueTask ExecuteCommand()

Logger?.LogInformation($"Reading file '{MeadowFile}' from device...\n");

var data = await device.ReadFileString(AppTools.SanitiseMeadowFilename(MeadowFile), CancellationToken);
var data = await device.ReadFileString(AppTools.SanitizeMeadowFilename(MeadowFile), CancellationToken);

if (data == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected override async ValueTask ExecuteCommand()

if (Folder != null)
{
Folder = AppTools.SanitiseMeadowFilename(Folder);
Folder = AppTools.SanitizeMeadowFolderName(Folder);

Logger?.LogInformation($"Getting file list from '{Folder}'...");
}
Expand Down
10 changes: 9 additions & 1 deletion Source/v2/Meadow.Cli/Commands/Current/File/FileReadCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ protected override async ValueTask ExecuteCommand()
var device = await GetCurrentDevice();
var connection = await GetCurrentConnection();

var state = await device.IsRuntimeEnabled(CancellationToken);

if (state == true)
{
Logger?.LogInformation($"{Strings.DisablingRuntime}...");
await device.RuntimeDisable(CancellationToken);
}

var received = 0;

connection.FileBytesReceived += (s, count) =>
Expand All @@ -43,7 +51,7 @@ protected override async ValueTask ExecuteCommand()
await device.RuntimeDisable();
}

var success = await device.ReadFile(AppTools.SanitiseMeadowFilename(MeadowFile), LocalFile, CancellationToken);
var success = await device.ReadFile(AppTools.SanitizeMeadowFilename(MeadowFile), LocalFile, CancellationToken);

if (success)
{
Expand Down
19 changes: 15 additions & 4 deletions Source/v2/Meadow.Cli/Commands/Current/File/FileWriteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ protected override async ValueTask ExecuteCommand()
var connection = await GetCurrentConnection();
var device = await GetCurrentDevice();

var state = await device.IsRuntimeEnabled(CancellationToken);

if (state == true)
{
Logger?.LogInformation($"{Strings.DisablingRuntime}...");
await device.RuntimeDisable(CancellationToken);
}

if (TargetFileNames.Any() && Files.Count != TargetFileNames.Count)
{
Logger?.LogError($"Number of files to write ({Files.Count}) does not match the number of target file names ({TargetFileNames.Count}).");
Expand All @@ -40,8 +48,11 @@ protected override async ValueTask ExecuteCommand()
{
var p = e.completed / (double)e.total * 100d;

// Console instead of Logger due to line breaking for progress bar
Console?.Output.Write($"Writing {e.fileName}: {p:0}% \r");
if (!double.IsNaN(p))
{
// Console instead of Logger due to line breaking for progress bar
Console?.Output.Write($"Writing {e.fileName}: {p:0}% \r");
}
};

Logger?.LogInformation($"Writing {Files.Count} file{(Files.Count > 1 ? "s" : "")} to device...");
Expand All @@ -54,7 +65,7 @@ protected override async ValueTask ExecuteCommand()
}
else
{
var targetFileName = AppTools.SanitiseMeadowFilename(GetTargetFileName(i));
var targetFileName = AppTools.SanitizeMeadowFilename(GetTargetFileName(i));

Logger?.LogInformation(
$"Writing '{Files[i]}' as '{targetFileName}' to device");
Expand Down Expand Up @@ -85,4 +96,4 @@ private string GetTargetFileName(int i)

return new FileInfo(Files[i]).Name;
}
}
}
12 changes: 10 additions & 2 deletions Source/v2/Meadow.Cli/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,21 @@
"commandName": "Project",
"commandLineArgs": "file list"
},
"File List folder": {
"commandName": "Project",
"commandLineArgs": "file list Temp"
},
"File List verbose": {
"commandName": "Project",
"commandLineArgs": "file list --verbose"
},
"File Delete": {
"commandName": "Project",
"commandLineArgs": "file delete Juego.pdb"
"commandLineArgs": "file delete /yo2.txt"
},
"File Delete folder": {
"commandName": "Project",
"commandLineArgs": "file delete /Temp/yo3.txt"
},
"File Delete All": {
"commandName": "Project",
Expand All @@ -105,7 +113,7 @@
},
"File Write": {
"commandName": "Project",
"commandLineArgs": "file write -f \"f:\\temp\\test.txt\""
"commandLineArgs": "file write -f .\\yo2.txt"
},
"Firmware List": {
"commandName": "Project",
Expand Down

0 comments on commit 39ce3f7

Please sign in to comment.