From 04d768e4fb75ec4e6eac322c559890f64908fa8d Mon Sep 17 00:00:00 2001
From: Leonhard Stemplinger <leonhard.stemplinger@trusteq.de>
Date: Wed, 9 Oct 2024 16:58:07 +0200
Subject: [PATCH] Make Powershell completion script work in constrained mode

Creating CompletionResult objects is not allowed in Powershell constrained mode, so return results as strings if constrained mode is enabled

Store results as PsCustomObjects instead of hashtables. This prevents Sort-Object from trying to convert the hashtable to a object, which is blocked in constrained mode.
PsCustomObjects are created using New-Object to work around https://github.com/PowerShell/PowerShell/issues/20767
---
 powershell_completions.go | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/powershell_completions.go b/powershell_completions.go
index a830b7bc..746dcb92 100644
--- a/powershell_completions.go
+++ b/powershell_completions.go
@@ -162,7 +162,10 @@ filter __%[1]s_escapeStringWithSpecialChars {
         if (-Not $Description) {
             $Description = " "
         }
-        @{Name="$Name";Description="$Description"}
+        New-Object -TypeName PSCustomObject -Property @{
+            Name = "$Name"
+            Description = "$Description"
+        }
     }
 
 
@@ -240,7 +243,12 @@ filter __%[1]s_escapeStringWithSpecialChars {
                     __%[1]s_debug "Only one completion left"
 
                     # insert space after value
-                    [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
+                    $CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space
+                    if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
+                        [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
+                    } else {
+                        $CompletionText
+                    }
 
                 } else {
                     # Add the proper number of spaces to align the descriptions
@@ -255,7 +263,12 @@ filter __%[1]s_escapeStringWithSpecialChars {
                         $Description = "  ($($comp.Description))"
                     }
 
-                    [System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
+                    $CompletionText = "$($comp.Name)$Description"
+                    if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
+                        [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
+                    } else {
+                        $CompletionText
+                    }
                 }
              }
 
@@ -264,7 +277,13 @@ filter __%[1]s_escapeStringWithSpecialChars {
                 # insert space after value
                 # MenuComplete will automatically show the ToolTip of
                 # the highlighted value at the bottom of the suggestions.
-                [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
+
+                $CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space
+                if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
+                    [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
+                } else {
+                    $CompletionText
+                }
             }
 
             # TabCompleteNext and in case we get something unknown
@@ -272,7 +291,13 @@ filter __%[1]s_escapeStringWithSpecialChars {
                 # Like MenuComplete but we don't want to add a space here because
                 # the user need to press space anyway to get the completion.
                 # Description will not be shown because that's not possible with TabCompleteNext
-                [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
+
+                $CompletionText = $($comp.Name | __%[1]s_escapeStringWithSpecialChars)
+                if ($ExecutionContext.SessionState.LanguageMode -eq "FullLanguage"){
+                    [System.Management.Automation.CompletionResult]::new($CompletionText, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
+                } else {
+                    $CompletionText
+                }
             }
         }