Skip to content

Commit

Permalink
Fix serialization of PSCustomObject wrapped object
Browse files Browse the repository at this point in the history
With the switch away from converting PSCustomObjects to dictionaries
we broke the way values that are wrapped in a PSCustomObject are serialized.

This is evident when values of hashtables are generated using Write-Output
which generates a PSCustomObject (Which is not evident in powershell, as
there is a lot of magic in powershell), but is clearly evident when we try
to use an object generated in PowerShell, in C#.

This change looks at the nested type of a PSCustomObject, and unwraps it
if it's not just another PSCustomObject.

Fixes: #157

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
  • Loading branch information
gabriel-samfira committed Dec 14, 2024
1 parent 7e2611b commit 9eeee79
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 1 deletion.
15 changes: 15 additions & 0 deletions Tests/powershell-yaml.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ Import-Module $modulePath
InModuleScope $moduleName {
$compareStrictly = Get-EquivalencyOption -Comparator Equality

Describe "Test PSCustomObject wrapped values are serialized correctly" {
Context "Wrapped values" {
It "Should serialize correctly" {
$expectBigInt = [System.Numerics.BigInteger]::Parse("9999999999999999999999999999999999999999999999999")
$obj = [PSCustomObject]@{a = Write-Output 'string'; b = Write-Output 1; c = Write-Output @{nested = $true};d = [pscustomobject]$expectBigInt}
$asYaml = ConvertTo-Yaml $obj
$fromYaml = ConvertFrom-Yaml $asYaml

Assert-Equivalent -Options $compareStrictly -Expected "string" -Actual $fromYaml["a"]
Assert-Equivalent -Options $compareStrictly -Expected 1 -Actual $fromYaml["b"]
Assert-Equivalent -Options $compareStrictly -Expected $expectBigInt -Actual $fromYaml["d"]
}
}
}

Describe "Test encode-decode symmetry." {

Context "Simple-Items" {
Expand Down
Binary file modified lib/net47/PowerShellYamlSerializer.dll
Binary file not shown.
Binary file modified lib/netstandard2.1/PowerShellYamlSerializer.dll
Binary file not shown.
12 changes: 11 additions & 1 deletion src/PowerShellYamlSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,17 @@ public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerialize
emitter.Emit(new Scalar(AnchorName.Empty, "tag:yaml.org,2002:null", "", ScalarStyle.Plain, true, false));
} else {
serializer(prop.Name, prop.Name.GetType());
serializer(prop.Value, prop.Value.GetType());
var objType = prop.Value.GetType();
var val = prop.Value;
if (prop.Value is PSObject nestedPsObj) {
var nestedType = nestedPsObj.BaseObject.GetType();
if (nestedType != typeof(System.Management.Automation.PSCustomObject)) {
objType = nestedPsObj.BaseObject.GetType();
val = nestedPsObj.BaseObject;
}
}
serializer(val, objType);

}
}
emitter.Emit(new MappingEnd());
Expand Down

0 comments on commit 9eeee79

Please sign in to comment.