Skip to content

Commit

Permalink
Fixed #203
Browse files Browse the repository at this point in the history
• Naming validation now also checks 0 length
• Naming validation now also checks for "." & ".."
• Added indication for valid Unix naming
• Rename is now canceled if naming rules for the filesystem are not met
  • Loading branch information
Alex4SSB committed Jun 26, 2024
1 parent 8b5a0b9 commit 7ebeac4
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 27 deletions.
29 changes: 25 additions & 4 deletions ADB Explorer/Controls/RenameTooltip.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ui:FontIcon>
<ui:FontIcon.Style>
Expand All @@ -34,7 +35,7 @@
<Setter Property="Glyph" Value="&#xF13D;" />
<Setter Property="Foreground" Value="{DynamicResource TrashDriveAltBorder}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static Member=models:Data.FileActions}, Path=IsRenameFuseLegal}" Value="True">
<DataTrigger Binding="{Binding Source={x:Static Member=models:Data.FileActions}, Path=IsRenameUnixLegal}" Value="True">
<Setter Property="Glyph" Value="&#xF13E;" />
<Setter Property="Foreground" Value="{DynamicResource NewDeviceAltBorder}" />
</DataTrigger>
Expand All @@ -49,7 +50,7 @@
<Setter Property="Glyph" Value="&#xF13D;" />
<Setter Property="Foreground" Value="{DynamicResource TrashDriveAltBorder}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static Member=models:Data.FileActions}, Path=IsRenameWindowsLegal}" Value="True">
<DataTrigger Binding="{Binding Source={x:Static Member=models:Data.FileActions}, Path=IsRenameFuseLegal}" Value="True">
<Setter Property="Glyph" Value="&#xF13E;" />
<Setter Property="Foreground" Value="{DynamicResource NewDeviceAltBorder}" />
</DataTrigger>
Expand All @@ -58,6 +59,21 @@
</ui:FontIcon.Style>
</ui:FontIcon>
<ui:FontIcon Grid.Row="2">
<ui:FontIcon.Style>
<Style BasedOn="{StaticResource GlyphFont}" TargetType="ui:FontIcon">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Glyph" Value="&#xF13D;" />
<Setter Property="Foreground" Value="{DynamicResource TrashDriveAltBorder}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static Member=models:Data.FileActions}, Path=IsRenameWindowsLegal}" Value="True">
<Setter Property="Glyph" Value="&#xF13E;" />
<Setter Property="Foreground" Value="{DynamicResource NewDeviceAltBorder}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ui:FontIcon.Style>
</ui:FontIcon>
<ui:FontIcon Grid.Row="3">
<ui:FontIcon.Style>
<Style BasedOn="{StaticResource GlyphFont}" TargetType="ui:FontIcon">
<Setter Property="FontWeight" Value="Bold" />
Expand All @@ -75,16 +91,21 @@
<TextBlock
Grid.Column="2"
VerticalAlignment="Center"
Text="Adheres to FUSE naming rules" />
Text="Adheres to Unix naming rules (via ADB)" />
<TextBlock
Grid.Row="1"
Grid.Column="2"
VerticalAlignment="Center"
Text="Adheres to Windows naming rules" />
Text="Adheres to FUSE naming rules" />
<TextBlock
Grid.Row="2"
Grid.Column="2"
VerticalAlignment="Center"
Text="Adheres to Windows naming rules" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
VerticalAlignment="Center"
Text="Adheres to Windows drive root naming rules" />
</Grid>
</Border>
Expand Down
45 changes: 35 additions & 10 deletions ADB Explorer/Helpers/File/FileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using ADB_Explorer.Models;
using ADB_Explorer.Resources;
using ADB_Explorer.Services;
using System.Xml.Linq;
using static ADB_Explorer.Models.AbstractFile;
using static ADB_Explorer.Models.FileClass;

Expand Down Expand Up @@ -211,24 +212,48 @@ where int.TryParse(i, out _)
return result;
}

public enum RenameTarget
{
Unix,
FUSE,
Windows,
}

static readonly Func<string, bool> FileNamePredicateWindows = (name) =>
!AdbExplorerConst.INVALID_WINDOWS_FILENAMES.Contains(name)
&& !name.Any(c => AdbExplorerConst.INVALID_NTFS_CHARS.Any(chr => chr == c))
&& name.Length > 0
&& name[^1] is not ' ' and not '.'
&& name[0] is not ' ';

static readonly Func<string, bool> FileNamePredicateFuse = (file) =>
!file.Any(c => AdbExplorerConst.INVALID_NTFS_CHARS.Contains(c));
static readonly Func<string, bool> FileNamePredicateFuse = (name) =>
!name.Any(c => AdbExplorerConst.INVALID_NTFS_CHARS.Contains(c))
&& name.Length > 0
&& name is not "." and not "..";

static readonly Func<string, bool> FileNamePredicateUnix = (name) =>
name.Length > 0
&& name is not "." and not "..";

public static bool FileNameLegal(string fileName, bool isWindows = false)
=> FileNameLegal(new[] { fileName }, isWindows);
public static bool FileNameLegal(string fileName, RenameTarget target)
=> FileNameLegal(new[] { fileName }, target);

public static bool FileNameLegal(FilePath file, bool isWindows = false)
=> FileNameLegal(new[] { file }, isWindows);
public static bool FileNameLegal(FilePath file, RenameTarget target)
=> FileNameLegal(new[] { file }, target);

public static bool FileNameLegal(IEnumerable<FilePath> files, bool isWindows = false)
=> FileNameLegal(files.Select(f => f.FullName), isWindows);
public static bool FileNameLegal(IEnumerable<FilePath> files, RenameTarget target)
=> FileNameLegal(files.Select(f => f.FullName), target);

public static bool FileNameLegal(IEnumerable<string> names, bool isWindows = false)
=> names.AnyAll(isWindows ? FileNamePredicateWindows : FileNamePredicateFuse);
public static bool FileNameLegal(IEnumerable<string> names, RenameTarget target)
{
var predicate = target switch
{
RenameTarget.Unix => FileNamePredicateUnix,
RenameTarget.FUSE => FileNamePredicateFuse,
RenameTarget.Windows => FileNamePredicateWindows,
_ => throw new NotSupportedException(),
};

return names.AnyAll(predicate);
}
}
8 changes: 5 additions & 3 deletions ADB Explorer/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1792,11 +1792,13 @@ private void NameColumnEdit_TextChanged(object sender, TextChangedEventArgs e)
var textBox = sender as TextBox;
textBox.FilterString(CurrentDrive.IsFUSE
? INVALID_NTFS_CHARS
: new[] { '/', '\\' });
: INVALID_UNIX_CHARS);

FileActions.IsRenameFuseLegal = FileHelper.FileNameLegal(textBox.Text);
FileActions.IsRenameUnixLegal = FileHelper.FileNameLegal(textBox.Text, FileHelper.RenameTarget.Unix);

FileActions.IsRenameWindowsLegal = FileHelper.FileNameLegal(textBox.Text, true);
FileActions.IsRenameFuseLegal = FileHelper.FileNameLegal(textBox.Text, FileHelper.RenameTarget.FUSE);

FileActions.IsRenameWindowsLegal = FileHelper.FileNameLegal(textBox.Text, FileHelper.RenameTarget.Windows);

FileActions.IsRenameDriveRootLegal = FileActions.IsRenameWindowsLegal
&& !INVALID_WINDOWS_ROOT_PATHS.Contains(textBox.Text);
Expand Down
1 change: 1 addition & 0 deletions ADB Explorer/Models/Static/Const.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public static class AdbExplorerConst

public static readonly char[] ESCAPE_ADB_SHELL_CHARS = { '(', ')', '<', '>', '|', ';', '&', '*', '\\', '~', '"', '\'', ' ', '$', '`' };
public static readonly char[] INVALID_NTFS_CHARS = { '"', '*', '/', ':', '<', '>', '?', '\\', '|' };
public static readonly char[] INVALID_UNIX_CHARS = { '/', '\\' };
public static readonly string[] INVALID_WINDOWS_FILENAMES = { "CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "COM¹", "COM²", "COM³", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", "LPT¹", "LPT²", "LPT³" };
public static readonly string[] INVALID_WINDOWS_ROOT_PATHS = { "$AttrDef", "$BadClus", "$Bitmap", "$Boot", "$LogFile", "$MFT", "$MFTMirr", "$Secure", "$UpCase", "$Volume", "$Extend", @"$Extend\$ObjId", @"$Extend\$Quota", @"$Extend\$Reparse" };

Expand Down
2 changes: 0 additions & 2 deletions ADB Explorer/Resources/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ public static class Strings
public const string S_REDIRECTION_ERROR_TITLE = "Deploy AdbProgressRedirection Error";
public const string S_REDIRECTION = "Progress Redirection ";
public const string S_LS_ERROR_TITLE = "List Directory Error";
public const string S_ILLEGAL_UNIX_NAME = "A file cannot be named '.' or '..'";
public const string S_ILLEGAL_UNIX_NAME_TITLE = "Illegal File Name";
public const string S_WIN_ROOT_ILLEGAL = "Some of the selected files cannot be created under a Windows drive root.";
public const string S_WIN_ROOT_ILLEGAL_TITLE = "Pull To Windows Drive Root";

Expand Down
13 changes: 5 additions & 8 deletions ADB Explorer/Services/AppInfra/FileAction/FileActionLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ public static bool IsPasteEnabled(bool isKeyboard = false)
}

Data.FileActions.IsPastingIllegalOnFuse = DriveHelper.GetCurrentDrive(targetPath)?.IsFUSE is true
&& !FileHelper.FileNameLegal(Data.CutItems);
&& !FileHelper.FileNameLegal(Data.CutItems, FileHelper.RenameTarget.FUSE);

if (Data.FileActions.IsPastingIllegalOnFuse)
return false;
Expand Down Expand Up @@ -467,13 +467,10 @@ public static void Rename(TextBox textBox)
FileClass file = TextHelper.GetAltObject(textBox) as FileClass;
var name = FileHelper.DisplayName(textBox);

if (textBox.Text is "." or "..")
{
if (file.IsTemp)
Data.DirList.FileList.Remove(file);

DialogService.ShowMessage(Strings.S_ILLEGAL_UNIX_NAME, Strings.S_ILLEGAL_UNIX_NAME_TITLE, DialogService.DialogIcon.Exclamation, copyToClipboard: true);

if (!Data.FileActions.IsRenameUnixLegal
|| (Data.CurrentDrive?.IsFUSE is true && !Data.FileActions.IsRenameFuseLegal))
{
return;
}

Expand Down Expand Up @@ -777,7 +774,7 @@ public static void UpdateFileActions()
Data.FileActions.DeleteDescription.Value = Data.FileActions.IsRecycleBin && !Data.SelectedFiles.Any() ? Strings.S_EMPTY_TRASH : Strings.S_DELETE_ACTION;
Data.FileActions.RestoreDescription.Value = Data.FileActions.IsRecycleBin && !Data.SelectedFiles.Any() ? Strings.S_RESTORE_ALL : Strings.S_RESTORE_ACTION;

Data.FileActions.IsSelectionIllegalOnWindows = !FileHelper.FileNameLegal(Data.SelectedFiles, true);
Data.FileActions.IsSelectionIllegalOnWindows = !FileHelper.FileNameLegal(Data.SelectedFiles, FileHelper.RenameTarget.Windows);

Data.FileActions.PullEnabled = !Data.FileActions.IsRecycleBin
&& Data.SelectedFiles.AnyAll(f => f.Type is not FileType.BrokenLink)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,13 @@ public bool IsApkWebSearchEnabled
set => Set(ref isApkWebSearchEnabled, value);
}

private bool isRenameUnixLegal = false;
public bool IsRenameUnixLegal
{
get => isRenameUnixLegal;
set => Set(ref isRenameUnixLegal, value);
}

private bool isRenameFuseLegal = false;
public bool IsRenameFuseLegal
{
Expand Down

0 comments on commit 7ebeac4

Please sign in to comment.