diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index b40e80a..61cdc47 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -21,6 +21,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#732](https://github.com/Icinga/icinga-powershell-framework/pull/732) Adds support for TLS 1.3 and improves startup response * [#735](https://github.com/Icinga/icinga-powershell-framework/pull/735) Adds support to provide occuring problem event id's for the Eventlog and corresponding acknowledgement id's, providing an indicator if certain issues are resolved or still present +* [#739](https://github.com/Icinga/icinga-powershell-framework/pull/739) Adds support to check the encoding of files to ensure we can properly load them and throw errors for unsupported encoding * [#740](https://github.com/Icinga/icinga-powershell-framework/pull/740) Adds new command `Invoke-IcingaForWindowsRESTApi` for easier API communication * [#742](https://github.com/Icinga/icinga-powershell-framework/pull/742) Adds support for the CPU provider to limit the CPU usage to 100% for each thread diff --git a/lib/core/installer/tools/Get-FileEncoding.psm1 b/lib/core/installer/tools/Get-FileEncoding.psm1 new file mode 100644 index 0000000..1500a0c --- /dev/null +++ b/lib/core/installer/tools/Get-FileEncoding.psm1 @@ -0,0 +1,68 @@ +<# +.SYNOPSIS + Determines the encoding of a file. + +.DESCRIPTION + The Get-FileEncoding function determines the encoding of a file by examining the file's byte order mark (BOM) or by checking if the file is ASCII or UTF8 without BOM. + +.PARAMETER Path + Specifies the path of the file to check. + +.EXAMPLE + Get-FileEncoding -Path "C:\path\to\file.txt" + Returns the encoding of the specified file. + +.OUTPUTS + System.String + The function returns a string representing the encoding of the file. Possible values are: + - UTF8-BOM: UTF-8 encoding with a byte order mark (BOM). + - Unicode: UTF-16 encoding (little-endian). + - BigEndianUnicode: UTF-16 encoding (big-endian). + - UTF7: UTF-7 encoding. + - UTF32: UTF-32 encoding. + - UTF8: UTF-8 encoding without a byte order mark (BOM). + - ASCII: ASCII encoding. + +.NOTES + This function requires PowerShell version 3.0 or later. +#> + +function Get-FileEncoding() +{ + param ( + [string]$Path = '' + ); + + if ([string]::IsNullOrEmpty($Path) -Or (Test-Path -Path $Path) -eq $FALSE) { + Write-IcingaConsoleError 'The specified file "{0}" was not found' -Objects $Path; + return $null; + } + + $Bytes = Get-Content -Encoding Byte -ReadCount 4 -TotalCount 4 -Path $Path; + + if ($Bytes[0] -eq 0xef -and $Bytes[1] -eq 0xbb -and $Bytes[2] -eq 0xbf) { + return 'UTF8-BOM'; + } elseif ($Bytes[0] -eq 0xff -and $Bytes[1] -eq 0xfe) { + return 'Unicode'; + } elseif ($Bytes[0] -eq 0xfe -and $Bytes[1] -eq 0xff) { + return 'BigEndianUnicode'; + } elseif ($Bytes[0] -eq 0x2b -and $Bytes[1] -eq 0x2f -and $Bytes[2] -eq 0x76) { + return 'UTF7'; + } elseif ($Bytes[0] -eq 0xff -and $Bytes[1] -eq 0xfe -and $Bytes[2] -eq 0x00 -and $Bytes[3] -eq 0x00) { + return 'UTF32'; + } else { + # Check if the file is ASCII or UTF8 without BOM + $Content = Get-Content -Encoding String -Path $Path; + $Bytes = [System.Text.Encoding]::UTF8.GetBytes($content); + + # Check each byte to see if it's outside the ASCII range + foreach ($byte in $Bytes) { + if ($byte -gt 127) { + return 'UTF8'; + } + } + } + + # This is the default encoding, as UTF8 without BOM could be valid ASCII + return 'ASCII'; +} diff --git a/lib/core/tools/Read-IcingaFileSecure.psm1 b/lib/core/tools/Read-IcingaFileSecure.psm1 index 3b7cbe8..25f36c6 100644 --- a/lib/core/tools/Read-IcingaFileSecure.psm1 +++ b/lib/core/tools/Read-IcingaFileSecure.psm1 @@ -39,9 +39,15 @@ function Read-IcingaFileSecure() [System.IO.FileShare]::Read ); - $ReadArray = New-Object Byte[] $FileStream.Length; - $UTF8Encoding = New-Object System.Text.UTF8Encoding $TRUE; - $FileContent = ''; + $ReadArray = New-Object Byte[] $FileStream.Length; + [bool]$UTF8BOM = $FALSE; + + if ((Get-FileEncoding -Path $File) -eq 'UTF8-BOM') { + $UTF8BOM = $TRUE; + } + + $UTF8Encoding = New-Object System.Text.UTF8Encoding $UTF8BOM; + $FileContent = ''; while ($FileStream.Read($ReadArray, 0 , $ReadArray.Length)) { $FileContent = [System.String]::Concat($FileContent, $UTF8Encoding.GetString($ReadArray));