From cb14e84a26acaf5863aa3bb094dbf18424798875 Mon Sep 17 00:00:00 2001 From: rbalsleyMSFT <53497092+rbalsleyMSFT@users.noreply.github.com> Date: Tue, 16 Sep 2025 16:43:43 -0700 Subject: [PATCH] Add robust sanitization for names used in paths Introduces a new common function, `ConvertTo-SafeName`, to sanitize strings by removing characters that are invalid in Windows file paths. This function is now used consistently when creating directory and file names for drivers (Dell, HP, Lenovo, Microsoft) and applications to prevent path-related errors. It replaces several ad-hoc sanitization methods with a single, more robust implementation. --- FFUDevelopment/BuildFFUVM.ps1 | 4 +++- FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 | 18 ++++++++++++++++++ .../FFU.Common/FFU.Common.Winget.psm1 | 6 ++++-- .../FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 | 14 ++++++++------ .../FFUUI.Core/FFUUI.Core.Drivers.HP.psm1 | 3 ++- .../FFUUI.Core/FFUUI.Core.Drivers.Lenovo.psm1 | 3 ++- .../FFUUI.Core.Drivers.Microsoft.psm1 | 4 +++- 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index d7964d8..9eb547f 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -904,8 +904,10 @@ function Get-MicrosoftDrivers { New-Item -Path $DriversFolder -ItemType Directory -Force | Out-Null WriteLog "Drivers folder created" } + $sanitizedModel = ConvertTo-SafeName -Name $Model + if ($sanitizedModel -ne $Model) { WriteLog "Sanitized model name: '$Model' -> '$sanitizedModel'" } $surfaceDriversPath = Join-Path -Path $DriversFolder -ChildPath $Make - $modelPath = Join-Path -Path $surfaceDriversPath -ChildPath $Model + $modelPath = Join-Path -Path $surfaceDriversPath -ChildPath $sanitizedModel if (-Not (Test-Path -Path $modelPath)) { WriteLog "Creating model folder: $modelPath" New-Item -Path $modelPath -ItemType Directory | Out-Null diff --git a/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 b/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 index ccb2998..099e720 100644 --- a/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 +++ b/FFUDevelopment/FFU.Common/FFU.Common.Core.psm1 @@ -194,4 +194,22 @@ function Set-Progress { WriteLog "[PROGRESS] $Percentage | $Message" } +function ConvertTo-SafeName { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [string]$Name + ) + # Replace invalid Windows filename characters (<>:"/\|?* and control chars) with a dash + $sanitized = $Name -replace '[<>:\"/\\|?*\x00-\x1F]', '-' + # Collapse multiple consecutive dashes + $sanitized = $sanitized -replace '-{2,}', '-' + # Trim leading/trailing spaces, periods, and dashes + $sanitized = $sanitized.Trim(' ','.','-') + if ([string]::IsNullOrWhiteSpace($sanitized)) { + $sanitized = 'Unnamed' + } + return $sanitized +} + Export-ModuleMember -Function * \ No newline at end of file diff --git a/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 b/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 index 4e205a2..5ab9b2d 100644 --- a/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 +++ b/FFUDevelopment/FFU.Common/FFU.Common.Winget.psm1 @@ -108,11 +108,13 @@ function Get-Application { # Determine app type and folder path $appIsWin32 = ($Source -eq 'msstore' -and $AppId.StartsWith("XP")) + $sanitizedAppName = ConvertTo-SafeName -Name $AppName + if ($sanitizedAppName -ne $AppName) { WriteLog "Sanitized app name: '$AppName' -> '$sanitizedAppName'" } if ($Source -eq 'winget' -or $appIsWin32) { - $appBaseFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $AppName + $appBaseFolderPath = Join-Path -Path "$AppsPath\Win32" -ChildPath $sanitizedAppName } else { - $appBaseFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $AppName + $appBaseFolderPath = Join-Path -Path "$AppsPath\MSStore" -ChildPath $sanitizedAppName } # If downloading multiple archs for a Win32 app, create a subfolder diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 index f86e2ca..271f6ac 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Dell.psm1 @@ -183,13 +183,15 @@ function Save-DellDriversTask { # Initial status update if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status "Checking..." } + $sanitizedModelName = ConvertTo-SafeName -Name $modelName + if ($sanitizedModelName -ne $modelName) { WriteLog "Sanitized model name: '$modelName' -> '$sanitizedModelName'" } $makeDriversPath = Join-Path -Path $DriversFolder -ChildPath $Make - $modelPath = Join-Path -Path $makeDriversPath -ChildPath $modelName - $driverRelativePath = Join-Path -Path $make -ChildPath $modelName # Relative path for the driver folder + $modelPath = Join-Path -Path $makeDriversPath -ChildPath $sanitizedModelName + $driverRelativePath = Join-Path -Path $make -ChildPath $sanitizedModelName # Relative path for the driver folder try { # Check for existing drivers - $existingDriver = Test-ExistingDriver -Make $make -Model $modelName -DriversFolder $DriversFolder -Identifier $modelName -ProgressQueue $ProgressQueue + $existingDriver = Test-ExistingDriver -Make $make -Model $sanitizedModelName -DriversFolder $DriversFolder -Identifier $modelName -ProgressQueue $ProgressQueue if ($null -ne $existingDriver) { # Add the 'Model' property to the return object for consistency if it's not there if (-not $existingDriver.PSObject.Properties['Model']) { @@ -198,14 +200,14 @@ function Save-DellDriversTask { # Special handling for existing folders that need compression if ($CompressToWim -and $existingDriver.Status -eq 'Already downloaded') { - $wimFilePath = Join-Path -Path $makeDriversPath -ChildPath "$($modelName).wim" - $sourceFolderPath = Join-Path -Path $makeDriversPath -ChildPath $modelName + $wimFilePath = Join-Path -Path $makeDriversPath -ChildPath "$($sanitizedModelName).wim" + $sourceFolderPath = Join-Path -Path $makeDriversPath -ChildPath $sanitizedModelName WriteLog "Attempting compression of existing folder '$sourceFolderPath' to '$wimFilePath'." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status "Compressing existing..." } try { Compress-DriverFolderToWim -SourceFolderPath $sourceFolderPath -DestinationWimPath $wimFilePath -WimName $modelName -WimDescription "Drivers for $modelName" -PreserveSource:$PreserveSourceOnCompress -ErrorAction Stop $existingDriver.Status = "Already downloaded & Compressed" - $existingDriver.DriverPath = Join-Path -Path $make -ChildPath "$($modelName).wim" + $existingDriver.DriverPath = Join-Path -Path $make -ChildPath "$($sanitizedModelName).wim" $existingDriver.Success = $true WriteLog "Successfully compressed existing drivers for $modelName to $wimFilePath." } diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.HP.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.HP.psm1 index b6da5d5..9708472 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.HP.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.HP.psm1 @@ -126,7 +126,8 @@ function Save-HPDriversTask { $modelName = $DriverItemData.Model $make = $DriverItemData.Make # Should be 'HP' $identifier = $modelName # Unique identifier for progress updates - $sanitizedModelName = $modelName -replace '[\\/:"*?<>|]', '_' + $sanitizedModelName = ConvertTo-SafeName -Name $modelName + if ($sanitizedModelName -ne $modelName) { WriteLog "Sanitized model name: '$modelName' -> '$sanitizedModelName'" } $hpDriversBaseFolder = Join-Path -Path $DriversFolder -ChildPath $make # Changed variable name for clarity $platformListXml = Join-Path -Path $hpDriversBaseFolder -ChildPath "PlatformList.xml" $modelSpecificFolder = Join-Path -Path $hpDriversBaseFolder -ChildPath $sanitizedModelName # Sanitize model name for folder path diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Lenovo.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Lenovo.psm1 index 5ccddb8..73577b8 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Lenovo.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Lenovo.psm1 @@ -106,7 +106,8 @@ function Save-LenovoDriversTask { $identifier = $DriverItemData.Model $machineType = $DriverItemData.MachineType $make = "Lenovo" - $sanitizedIdentifier = $identifier -replace '[\\/:"*?<>|]', '_' + $sanitizedIdentifier = ConvertTo-SafeName -Name $identifier + if ($sanitizedIdentifier -ne $identifier) { WriteLog "Sanitized model identifier: '$identifier' -> '$sanitizedIdentifier'" } $status = "Starting..." $success = $false diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Microsoft.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Microsoft.psm1 index 69e892d..7bacb37 100644 --- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Microsoft.psm1 +++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Drivers.Microsoft.psm1 @@ -234,8 +234,10 @@ function Save-MicrosoftDriversTask { WriteLog "Creating Drivers folder: $DriversFolder" New-Item -Path $DriversFolder -ItemType Directory -Force | Out-Null } + $sanitizedModelName = ConvertTo-SafeName -Name $modelName + if ($sanitizedModelName -ne $modelName) { WriteLog "Sanitized model name: '$modelName' -> '$sanitizedModelName'" } $makeDriversPath = Join-Path -Path $DriversFolder -ChildPath $Make - $modelPath = Join-Path -Path $makeDriversPath -ChildPath $modelName + $modelPath = Join-Path -Path $makeDriversPath -ChildPath $sanitizedModelName if (-Not (Test-Path -Path $modelPath)) { WriteLog "Creating model folder: $modelPath" New-Item -Path $modelPath -ItemType Directory -Force | Out-Null