Skip to content

Commit d01b092

Browse files
author
James Brundage
committed
Invoke-PipeScript: Fixing [Parameter] leak (#69) and adding documentation.
1 parent e916719 commit d01b092

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

Invoke-PipeScript.ps1

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,10 @@
377377

378378
# Check that the AttributeSyntaxTree is not a real type (return if it is)
379379
$attributeType = $AttributeSyntaxTree.TypeName.GetReflectionType()
380-
if ($attributeType) { return $AttributeSyntaxTree }
380+
if ($attributeType) { return }
381381

382382
# Check that the typename is not [Ordered] (return if it is).
383-
if ($AttributeSyntaxTree.TypeName.Name -eq 'ordered') { return $AttributeSyntaxTree }
383+
if ($AttributeSyntaxTree.TypeName.Name -eq 'ordered') { return }
384384

385385
# Create a collection for stringified arguments.
386386
$stringArguments = @()
@@ -393,53 +393,72 @@
393393
$AttributeSyntaxTree.TypeName.Name
394394
}
395395

396+
# See if we could find a transpiler that fits.
396397
$foundTranspiler =
397398
if ($InputObject) {
398399
Get-Transpiler -TranspilerName "$transpilerStepName" -CouldPipe $InputObject |
399400
Select-Object -ExpandProperty ExtensionCommand
400401
} else {
401402
Get-Transpiler -TranspilerName "$transpilerStepName"
402403
}
403-
404+
405+
# Collect all of the arguments of the attribute, in the order they were specified.
404406
$argsInOrder = @(
405407
@($AttributeSyntaxTree.PositionalArguments) + @($AttributeSyntaxTree.NamedArguments) | Sort-Object { $_.Extent.StartOffset})
406408

409+
410+
# Now we need to map each of those arguments into either named or positional arguments.
407411
foreach ($attributeArg in $argsInOrder) {
412+
# Named arguments are fairly straightforward:
408413
if ($attributeArg -is [Management.Automation.Language.NamedAttributeArgumentAst]) {
409414
$argName = $attributeArg.ArgumentName
410415
$argAst = $attributeArg.Argument
411416
$parameter[$argName] =
412-
if ($argName -eq $argAst) {
413-
$true
414-
} elseif ($argAst.Value) {
415-
$argAst.Value.ToString()
416-
}
417+
if ($argName -eq $argAst) { # If the argument is the name,
418+
$true # treat it as a [switch] parameter.
419+
}
420+
# If the argument value was an ScriptBlockExpression
417421
elseif ($argAst -is [Management.Automation.Language.ScriptBlockExpressionAST]) {
422+
# Turn it into a [ScriptBlock]
418423
$argScriptBlock = [ScriptBlock]::Create($argAst.Extent.ToString() -replace '^\{' -replace '\}$')
424+
# If the Transpiler had a parameter that took a [ScriptBlock] or [ScriptBlock[]]
419425
if ($foundTranspiler.parameters.$argName.ParameterType -eq [ScriptBlock] -or
420426
$foundTranspiler.parameters.$argName.ParameterType -eq [ScriptBlock[]]) {
421-
$argScriptBlock
422-
} elseif ($SafeScriptBlockAttributeEvaluation) {
427+
$argScriptBlock # pass the [ScriptBlock] directly.
428+
}
429+
# Now here is where things get a bit more interesting:
430+
# If the parameter type _was not_ a [ScriptBlock], we can evaluate the [ScriptBlock] to create a real value
431+
# If we want to do this "safely", we can pass -SafeScriptBlockAttributeEvaluation
432+
elseif ($SafeScriptBlockAttributeEvaluation) {
433+
# Which will run the [ScriptBlock] inside of a data block, thus preventing it from running commands.
423434
& ([ScriptBlock]::Create("data {$argScriptBlock}"))
424435
} else {
436+
# Otherwise, we want to run the [ScriptBlock] directly.
425437
& ([ScriptBlock]::Create("$argScriptBlock"))
426438
}
427439
}
440+
elseif ($argAst.Value) {
441+
$argAst.Value.ToString()
442+
}
428443
else {
429444
$argAst.Extent.ToString()
430445
}
431446
} else {
432-
foreach ($eachParameter in $foundTranspiler.Parameters.Values) {
433-
$eachParameter
434-
}
447+
# If we are a positional parameter, for the moment:
435448
if ($parameter.Count) {
449+
# add it to the last named parameter.
436450
$parameter[@($parameter.Keys)[-1]] = @() + $parameter[@($parameter.Keys)[-1]] + $attributeArg.Value.ToString()
437451
} else {
452+
# Or add it to the list of string arguments.
438453
$stringArguments += "$($attributeArg.Value)"
439454
}
455+
456+
# We _should_ get more intelligent over time here.
457+
# See [the GitHub Issue](https://github.com/StartAutomating/PipeScript/issues/70) for more details.
440458
}
441459
}
442460

461+
# If we have found a transpiler, run it.
443462
if ($foundTranspiler) {
444463
$ArgumentList += $stringArguments
445464
if ($InputObject) {
@@ -490,11 +509,11 @@
490509
# Determine if the -Command is a real type.
491510
$realType = $Command.TypeName.GetReflectionType()
492511
if ($realType) {
493-
# If it is, return the connstraint unmodified.
494-
return $command
512+
# If it is, return.
513+
return
495514
}
496515
# Next, make sure it's not ```[ordered]``` (return it if is)
497-
if ($command.TypeName.Name -eq 'ordered') { return $command }
516+
if ($command.TypeName.Name -eq 'ordered') { return}
498517

499518
# Determine the name of the transpiler step.
500519
$transpilerStepName =

0 commit comments

Comments
 (0)